perm filename DVITYP.DIF[WEB,ALS] blob sn#684313 filedate 1982-09-16 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00072 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00012 00002	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,1
C00016 00003	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,2
C00020 00004	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,3
C00024 00005	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,3
C00028 00006	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,4
C00032 00007	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,4
C00034 00008	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,4
C00036 00009	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,4
C00038 00010	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,4
C00040 00011	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,4
C00044 00012	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5
C00049 00013	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5
C00054 00014	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5
C00059 00015	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5
C00064 00016	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5
C00069 00017	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5
C00074 00018	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5
C00078 00019	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5
C00082 00020	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,6
C00086 00021	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,6
C00090 00022	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,6
C00093 00023	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,6
C00097 00024	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,6
C00101 00025	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,6
C00105 00026	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,7
C00110 00027	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,7
C00114 00028	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,7
C00118 00029	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,7
C00122 00030	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,7
C00126 00031	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,7
C00130 00032	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8
C00135 00033	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8
C00140 00034	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8
C00144 00035	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8
C00148 00036	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8
C00152 00037	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8
C00156 00038	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8
C00159 00039	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8
C00163 00040	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8
C00167 00041	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,9
C00171 00042	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,9
C00175 00043	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,9
C00179 00044	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,9
C00183 00045	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,9
C00187 00046	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,9
C00191 00047	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,9
C00196 00048	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11
C00201 00049	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11
C00205 00050	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11
C00210 00051	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11
C00214 00052	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11
C00218 00053	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11
C00222 00054	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11
C00225 00055	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11
C00228 00056	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11
C00231 00057	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11
C00234 00058	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11
C00237 00059	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11
C00240 00060	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11
C00243 00061	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11
C00246 00062	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11
C00249 00063	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,12
C00253 00064	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,12
C00257 00065	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,12
C00261 00066	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,13
C00265 00067	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,14
C00269 00068	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,14
C00273 00069	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,14
C00277 00070	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,15
C00280 00071	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,15
C00284 00072	  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,15
C00286 ENDMK
C⊗;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,1

**** File 1) DVITYP.WEB[WEB,ALS]/1P/1L
1)	% This program by D. E. Knuth is not copyrighted and can be used freely.
1)	% But don't try to use it extensively, since it hasn't been very well
1)	% debugged yet... This is an experimental version.
1)	% Here is TeX material that gets inserted after \input webhdr
**** File 2) DVITYP.WEB[PAS,DEK]/1P/1L
2)	COMMENT ⊗   VALID 00017 PAGES
2)	C REC  PAGE   DESCRIPTION
2)	C00001 00001
2)	C00003 00002	% This program by D. E. Knuth is not copyrighted and can be used freely.
2)	C00006 00003	@* Introduction.
2)	C00016 00004	@* The character set.
2)	C00024 00005	@* Device-independent file format.
2)	C00072 00006	@* Input from binary files.
2)	C00085 00007	@* Reading the font information.
2)	C00103 00008	@* Optional modes of output.
2)	C00119 00009	@* Defining fonts.
2)	C00129 00010	@* Low level output routines.
2)	C00131 00011	@* Translation to symbolic form.
2)	C00156 00012	@* Skipping pages.
2)	C00160 00013	@* Using the backpointers.
2)	C00167 00014	@* Reading the postamble.
2)	C00178 00015	@* The main program.
2)	C00184 00016	@* System-dependent changes.
2)	C00185 00017	@* Index.
2)	C00186 ENDMK
2)	C⊗;
2)	% This program by D. E. Knuth is not copyrighted and can be used freely.
2)	% Version 1 was completed in September, 1982.
2)	% Here is TeX material that gets inserted after \input webhdr
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/21L
1)	  \vfill
1)	  \ctrline{\:E The {\:D DVItype} processor}
1)	  \vskip 15pt
1)	  \ctrline{(Version 0.6, slightly more than semi-debugged)}
1)	  \vfill}
1)	\def\botofcontents{\vfill
1)	  \ctrline{\ragged0\spaceskip0pt\xspaceskip0pt\baselineskip9pt
1)	    \hbox par 5in{\:bThe preparation of this report
1)	    was supported in part by the National Science
1)	    Foundation under grants IST-8201926 and MCS-7723738;
1)	    by Office of Naval Research grant N00014-81-K-0330;
1)	    and by the System Development Foundation. `\TeX' is a
1)	    trademark of the American Mathematical Society.}}}
1)	\setcount0 \contentspagenumber
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,2

**** File 2) DVITYP.WEB[PAS,DEK]/2P/20L
2)		\vfill
2)		\ctrline{\:E The {\:D DVItype} processor}
2)		\vskip 15pt
2)		\ctrline{(Version 1)}
2)		\vfill}
2)	\def\botofcontents{\vfill
2)		\ctrline{\ragged0\spaceskip0pt\xspaceskip0pt\baselineskip9pt
2)			\hbox par 5in{\:bThe preparation of this report
2)			was supported in part by the National Science
2)			Foundation under grants IST-8201926 and MCS-7723738,
2)			and by the System Development Foundation. `\TeX' is a
2)			trademark of the American Mathematical Society.}}}
2)	\setcount0 \contentspagenumber
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/75L
1)	@d banner=='This is DVItype, Version 0.6' {printed when the program starts}
1)	@ This program is written in standard \PASCAL, except where it is necessary
**** File 2) DVITYP.WEB[PAS,DEK]/3P/36L
2)	@d banner=='This is DVItype, Version 1' {printed when the program starts}
2)	@ This program is written in standard \PASCAL, except where it is necessary
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/100L
1)	@d random←reading==true {should we skip around in the file?}
1)	@d othercases == others: {default for cases not listed explicitly}
**** File 2) DVITYP.WEB[PAS,DEK]/3P/61L
2)	@d random_reading==true {should we skip around in the file?}
2)	@d othercases == others: {default for cases not listed explicitly}
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/106L
1)	@ The binary input comes from |dvi←file|, and the symbolic output is written
1)	on \PASCAL's standard |output| file. The term |print| is used instead of
**** File 2) DVITYP.WEB[PAS,DEK]/3P/67L
2)	@ The binary input comes from |dvi_file|, and the symbolic output is written
2)	on \PASCAL's standard |output| file. The term |print| is used instead of
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/112L
1)	@d print←ln(#)==write←ln(#)
1)	@p program DVI←type(@!dvi←file,@!output);
1)	label @<Labels in the outer block@>@/
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,3

**** File 2) DVITYP.WEB[PAS,DEK]/3P/73L
2)	@d print_ln(#)==write_ln(#)
2)	@p program DVI_type(@!dvi_file,@!output);
2)	label @<Labels in the outer block@>@/
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/120L
1)	  var i:integer; {loop index for initializations}
1)	  begin print←ln(banner);@/
1)	  @<Set initial values@>@/
1)	  end;
1)	@ If the program has to stop prematurely, it goes to the
1)	`|final←end|'. Another label, |done|, is used when stopping normally.
1)	@d final←end=9999 {label for the end of it all}
1)	@d done=30 {go here when finished with a subtask}
1)	@<Labels...@>=final←end,done;
1)	@ The following parameters can be changed at compile time to extend or
**** File 2) DVITYP.WEB[PAS,DEK]/3P/81L
2)		var i:integer; {loop index for initializations}
2)		begin print_ln(banner);@/
2)		@<Set initial values@>@/
2)		end;
2)	@ If the program has to stop prematurely, it goes to the
2)	`|final_end|'. Another label, |done|, is used when stopping normally.
2)	@d final_end=9999 {label for the end of it all}
2)	@d done=30 {go here when finished with a subtask}
2)	@<Labels...@>=final_end,done;
2)	@ The following parameters can be changed at compile time to extend or
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/137L
1)	@!max←fonts=100; {maximum number of distinct fonts per \.{DVI} file}
1)	@!max←widths=10000; {maximum number of different characters among all fonts}
1)	@!line←length=80; {bracketed lines of output will be at most this long}
1)	@!terminal←line←length=150; {maximum number of characters input in a single
1)	  line of input from the terminal}
1)	@!stack←size=100; {\.{DVI} files shouldn't |push| beyond this depth}
1)	@!name←size=1000; {total length of all font file names}
1)	@!name←length=50; {a file name shouldn't be longer than this}
1)	@ Here are some macros for common programming idioms.
1)	@d incr(#) == #:=#+1 {increase a variable by unity}
1)	@d decr(#) == #:=#-1 {decrease a variable by unity}
1)	@d do←nothing == {empty statement}
1)	@ If the \.{DVI} file is badly malformed, the whole process must be aborted;
**** File 2) DVITYP.WEB[PAS,DEK]/3P/98L
2)	@!max_fonts=100; {maximum number of distinct fonts per \.{DVI} file}
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,3

2)	@!max_widths=10000; {maximum number of different characters among all fonts}
2)	@!line_length=80; {bracketed lines of output will be at most this long}
2)	@!terminal_line_length=150; {maximum number of characters input in a single
2)		line of input from the terminal}
2)	@!stack_size=100; {\.{DVI} files shouldn't |push| beyond this depth}
2)	@!name_size=1000; {total length of all font file names}
2)	@!name_length=50; {a file name shouldn't be longer than this}
2)	@ Here are some macros for common programming idioms.
2)	@d incr(#) == #←#+1 {increase a variable by unity}
2)	@d decr(#) == #←#-1 {decrease a variable by unity}
2)	@d do_nothing == {empty statement}
2)	@ If the \.{DVI} file is badly malformed, the whole process must be aborted;
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/157L
1)	so a procedure called |jump←out| has been introduced. This procedure, which
1)	simply transfers control to the label |final←end| at the end of the program,
1)	contains the only non-local |goto| statement in \.{DVItype}.
1)	@↑system dependencies@>
1)	@d abort(#)==begin print(' ',#); jump←out;
1)	    end
1)	@d bad←dvi(#)==abort('Bad DVI file: ',#,'!')
1)	@.Bad DVI file@>
1)	@p procedure jump←out;
1)	begin goto final←end;
1)	end;
**** File 2) DVITYP.WEB[PAS,DEK]/3P/118L
2)	so a procedure called |jump_out| has been introduced. This procedure, which
2)	simply transfers control to the label |final_end| at the end of the program,
2)	contains the only non-local |goto| statement in \.{DVItype}.
2)	@↑system dependencies@>
2)	@d abort(#)==begin print(' ',#); jump_out;
2)			end
2)	@d bad_dvi(#)==abort('Bad DVI file: ',#,'!')
2)	@.Bad DVI file@>
2)	@p procedure jump_out;
2)	begin goto final_end;
2)	end;
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/185L
1)	@!ascii←code=" ".."~"; {a subrange of the integers}
1)	@ The original \PASCAL\ compiler was designed in the late 60s, when six-bit
**** File 2) DVITYP.WEB[PAS,DEK]/4P/15L
2)	@!ascii_code=" ".."~"; {a subrange of the integers}
2)	@ The original \PASCAL\ compiler was designed in the late 60s, when six-bit
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,4

***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/199L
1)	the name |text←char| to stand for the data type of the characters in the
1)	output file.  We shall also assume that |text←char| consists of
1)	the elements |chr(first←text←char)| through |chr(last←text←char)|,
1)	inclusive. The following definitions should be adjusted if necessary.
1)	@↑system dependencies@>
1)	@d text←char == char {the data type of characters in text files}
1)	@d first←text←char=0 {ordinal number of the smallest element of |text←char|}
1)	@d last←text←char=127 {ordinal number of the largest element of |text←char|}
1)	@<Types...@>=
1)	@!text←file=packed file of text←char;
1)	@ The \.{DVItype} processor converts between ascii code and
**** File 2) DVITYP.WEB[PAS,DEK]/4P/29L
2)	the name |text_char| to stand for the data type of the characters in the
2)	output file.  We shall also assume that |text_char| consists of
2)	the elements |chr(first_text_char)| through |chr(last_text_char)|,
2)	inclusive. The following definitions should be adjusted if necessary.
2)	@↑system dependencies@>
2)	@d text_char == char {the data type of characters in text files}
2)	@d first_text_char=0 {ordinal number of the smallest element of |text_char|}
2)	@d last_text_char=127 {ordinal number of the largest element of |text_char|}
2)	@<Types...@>=
2)	@!text_file=packed file of text_char;
2)	@ The \.{DVItype} processor converts between ascii code and
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/217L
1)	@!xord: array [text←char] of ascii←code;
1)	  {specifies conversion of input characters}
1)	@!xchr: array [0..255] of text←char;
1)	  {specifies conversion of output characters}
1)	@ Under our assumption that the visible characters of standard ascii are
**** File 2) DVITYP.WEB[PAS,DEK]/4P/47L
2)	@!xord: array [text_char] of ascii_code;
2)		{specifies conversion of input characters}
2)	@!xchr: array [0..255] of text_char;
2)		{specifies conversion of output characters}
2)	@ Under our assumption that the visible characters of standard ascii are
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/227L
1)	for i:=0 to @'37 do xchr[i]:='?';
1)	xchr[@'40]:=' ';
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,4

1)	xchr[@'41]:='!';
1)	xchr[@'42]:='"';
1)	xchr[@'43]:='#';
1)	xchr[@'44]:='$';
1)	xchr[@'45]:='%';
1)	xchr[@'46]:='&';
1)	xchr[@'47]:='''';@/
1)	xchr[@'50]:='(';
1)	xchr[@'51]:=')';
1)	xchr[@'52]:='*';
1)	xchr[@'53]:='+';
1)	xchr[@'54]:=',';
1)	xchr[@'55]:='-';
1)	xchr[@'56]:='.';
1)	xchr[@'57]:='/';@/
1)	xchr[@'60]:='0';
1)	xchr[@'61]:='1';
1)	xchr[@'62]:='2';
1)	xchr[@'63]:='3';
1)	xchr[@'64]:='4';
1)	xchr[@'65]:='5';
1)	xchr[@'66]:='6';
1)	xchr[@'67]:='7';@/
1)	xchr[@'70]:='8';
1)	xchr[@'71]:='9';
1)	xchr[@'72]:=':';
1)	xchr[@'73]:=';';
1)	xchr[@'74]:='<';
1)	xchr[@'75]:='=';
1)	xchr[@'76]:='>';
1)	xchr[@'77]:='?';@/
1)	xchr[@'100]:='@@';
1)	xchr[@'101]:='A';
1)	xchr[@'102]:='B';
1)	xchr[@'103]:='C';
1)	xchr[@'104]:='D';
1)	xchr[@'105]:='E';
1)	xchr[@'106]:='F';
1)	xchr[@'107]:='G';@/
1)	xchr[@'110]:='H';
1)	xchr[@'111]:='I';
1)	xchr[@'112]:='J';
1)	xchr[@'113]:='K';
1)	xchr[@'114]:='L';
1)	xchr[@'115]:='M';
1)	xchr[@'116]:='N';
1)	xchr[@'117]:='O';@/
1)	xchr[@'120]:='P';
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,4

1)	xchr[@'121]:='Q';
1)	xchr[@'122]:='R';
1)	xchr[@'123]:='S';
1)	xchr[@'124]:='T';
1)	xchr[@'125]:='U';
1)	xchr[@'126]:='V';
1)	xchr[@'127]:='W';@/
1)	xchr[@'130]:='X';
1)	xchr[@'131]:='Y';
1)	xchr[@'132]:='Z';
1)	xchr[@'133]:='[';
1)	xchr[@'134]:='\';
1)	xchr[@'135]:=']';
1)	xchr[@'136]:='↑';
1)	xchr[@'137]:='←';@/
1)	xchr[@'140]:='`';
1)	xchr[@'141]:='a';
1)	xchr[@'142]:='b';
1)	xchr[@'143]:='c';
1)	xchr[@'144]:='d';
1)	xchr[@'145]:='e';
1)	xchr[@'146]:='f';
1)	xchr[@'147]:='g';@/
1)	xchr[@'150]:='h';
1)	xchr[@'151]:='i';
1)	xchr[@'152]:='j';
1)	xchr[@'153]:='k';
1)	xchr[@'154]:='l';
1)	xchr[@'155]:='m';
1)	xchr[@'156]:='n';
1)	xchr[@'157]:='o';@/
1)	xchr[@'160]:='p';
1)	xchr[@'161]:='q';
1)	xchr[@'162]:='r';
1)	xchr[@'163]:='s';
1)	xchr[@'164]:='t';
1)	xchr[@'165]:='u';
1)	xchr[@'166]:='v';
1)	xchr[@'167]:='w';@/
1)	xchr[@'170]:='x';
1)	xchr[@'171]:='y';
1)	xchr[@'172]:='z';
1)	xchr[@'173]:='{';
1)	xchr[@'174]:='|';
1)	xchr[@'175]:='}';
1)	xchr[@'176]:='~';
1)	for i:=@'177 to 255 do xchr[i]:='?';
1)	@ The following system-independent code makes the |xord| array contain a
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,4

**** File 2) DVITYP.WEB[PAS,DEK]/4P/57L
2)	for i←0 to @'37 do xchr[i]←'?';
2)	xchr[@'40]←' ';
2)	xchr[@'41]←'!';
2)	xchr[@'42]←'"';
2)	xchr[@'43]←'#';
2)	xchr[@'44]←'$';
2)	xchr[@'45]←'%';
2)	xchr[@'46]←'&';
2)	xchr[@'47]←'''';@/
2)	xchr[@'50]←'(';
2)	xchr[@'51]←')';
2)	xchr[@'52]←'*';
2)	xchr[@'53]←'+';
2)	xchr[@'54]←',';
2)	xchr[@'55]←'-';
2)	xchr[@'56]←'.';
2)	xchr[@'57]←'/';@/
2)	xchr[@'60]←'0';
2)	xchr[@'61]←'1';
2)	xchr[@'62]←'2';
2)	xchr[@'63]←'3';
2)	xchr[@'64]←'4';
2)	xchr[@'65]←'5';
2)	xchr[@'66]←'6';
2)	xchr[@'67]←'7';@/
2)	xchr[@'70]←'8';
2)	xchr[@'71]←'9';
2)	xchr[@'72]←':';
2)	xchr[@'73]←';';
2)	xchr[@'74]←'<';
2)	xchr[@'75]←'=';
2)	xchr[@'76]←'>';
2)	xchr[@'77]←'?';@/
2)	xchr[@'100]←'@@';
2)	xchr[@'101]←'A';
2)	xchr[@'102]←'B';
2)	xchr[@'103]←'C';
2)	xchr[@'104]←'D';
2)	xchr[@'105]←'E';
2)	xchr[@'106]←'F';
2)	xchr[@'107]←'G';@/
2)	xchr[@'110]←'H';
2)	xchr[@'111]←'I';
2)	xchr[@'112]←'J';
2)	xchr[@'113]←'K';
2)	xchr[@'114]←'L';
2)	xchr[@'115]←'M';
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,4

2)	xchr[@'116]←'N';
2)	xchr[@'117]←'O';@/
2)	xchr[@'120]←'P';
2)	xchr[@'121]←'Q';
2)	xchr[@'122]←'R';
2)	xchr[@'123]←'S';
2)	xchr[@'124]←'T';
2)	xchr[@'125]←'U';
2)	xchr[@'126]←'V';
2)	xchr[@'127]←'W';@/
2)	xchr[@'130]←'X';
2)	xchr[@'131]←'Y';
2)	xchr[@'132]←'Z';
2)	xchr[@'133]←'[';
2)	xchr[@'134]←'\';
2)	xchr[@'135]←']';
2)	xchr[@'136]←'↑';
2)	xchr[@'137]←'_';@/
2)	xchr[@'140]←'`';
2)	xchr[@'141]←'a';
2)	xchr[@'142]←'b';
2)	xchr[@'143]←'c';
2)	xchr[@'144]←'d';
2)	xchr[@'145]←'e';
2)	xchr[@'146]←'f';
2)	xchr[@'147]←'g';@/
2)	xchr[@'150]←'h';
2)	xchr[@'151]←'i';
2)	xchr[@'152]←'j';
2)	xchr[@'153]←'k';
2)	xchr[@'154]←'l';
2)	xchr[@'155]←'m';
2)	xchr[@'156]←'n';
2)	xchr[@'157]←'o';@/
2)	xchr[@'160]←'p';
2)	xchr[@'161]←'q';
2)	xchr[@'162]←'r';
2)	xchr[@'163]←'s';
2)	xchr[@'164]←'t';
2)	xchr[@'165]←'u';
2)	xchr[@'166]←'v';
2)	xchr[@'167]←'w';@/
2)	xchr[@'170]←'x';
2)	xchr[@'171]←'y';
2)	xchr[@'172]←'z';
2)	xchr[@'173]←'{';
2)	xchr[@'174]←'|';
2)	xchr[@'175]←'}';
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,4

2)	xchr[@'176]←'~';
2)	for i←@'177 to 255 do xchr[i]←'?';
2)	@ The following system-independent code makes the |xord| array contain a
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/329L
1)	for i:=first←text←char to last←text←char do xord[chr(i)]:=@'40;
1)	for i:=" " to "~" do xord[xchr[i]]:=i;
1)	@* Device-independent file format.
**** File 2) DVITYP.WEB[PAS,DEK]/4P/159L
2)	for i←first_text_char to last_text_char do xord[chr(i)]←@'40;
2)	for i←" " to "~" do xord[xchr[i]]←i;
2)	@* Device-independent file format.
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/344L
1)	of several consecutive bytes; for example, the `|set←rule|' command has two
1)	parameters, each of which is four bytes long. Parameters are usually
**** File 2) DVITYP.WEB[PAS,DEK]/5P/13L
2)	of several consecutive bytes; for example, the `|set_rule|' command has two
2)	parameters, each of which is four bytes long. Parameters are usually
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/360L
1)	numerical order. If we ignore |nop| commands and \\{fnt\←def} commands
1)	(which are allowed between any two commands in the file), each |eop|
**** File 2) DVITYP.WEB[PAS,DEK]/5P/29L
2)	numerical order. If we ignore |nop| commands and \\{fnt\_def} commands
2)	(which are allowed between any two commands in the file), each |eop|
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/384L
1)	by \\{fnt} and \\{fnt\←num} commands. (b)@@The current position on the page
1)	is given by two numbers called the horizontal and vertical coordinates,
**** File 2) DVITYP.WEB[PAS,DEK]/5P/53L
2)	by \\{fnt} and \\{fnt\_num} commands. (b)@@The current position on the page
2)	is given by two numbers called the horizontal and vertical coordinates,
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/411L
1)	\yskip\hang|set←char←0| 0. Typeset character number@@0 from font@@|f|
1)	such that the reference point of the character is at |(h,v)|. Then
**** File 2) DVITYP.WEB[PAS,DEK]/5P/80L
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5

2)	\yskip\hang|set_char_0| 0. Typeset character number@@0 from font@@|f|
2)	such that the reference point of the character is at |(h,v)|. Then
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/417L
1)	\yskip\hang|set←char←1| through |set←char←127| (opcodes 1 to 127).
1)	Do the operations of |set←char←0|, but use the appropriate character number
1)	instead of character@@0.
1)	\yskip\hang|set1| 128 |c[1]|. Same as |set←char←0|, except that character
1)	number@@|c| is typeset. \TeX82 uses this command for characters in the
1)	range |128<=c<256|.
1)	\yskip\hang|set2| 129 |c[2]|. Same as |set1|, except that@@|c| is two
1)	bytes long, so it is in the range |0<=c<65536|. \TeX82 never uses this
1)	command, which is intended for processors that deal with oriental languages;
**** File 2) DVITYP.WEB[PAS,DEK]/5P/86L
2)	\yskip\hang|set_char_1| through |set_char_127| (opcodes 1 to 127).
2)	Do the operations of |set_char_0|, but use the appropriate character number
2)	instead of character@@0.
2)	\yskip\hang|set1| 128 |c[1]|. Same as |set_char_0|, except that character
2)	number@@|c| is typeset. \TeX82 uses this command for characters in the
2)	range |128≤c<256|.
2)	\yskip\hang|set2| 129 |c[2]|. Same as |set1|, except that@@|c| is two
2)	bytes long, so it is in the range |0≤c<65536|. \TeX82 never uses this
2)	command, which is intended for processors that deal with oriental languages;
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/440L
1)	\yskip\hang|set←rule| 132 |a[4]| |b[4]|. Typeset a solid black rectangle
1)	of height |a| and width |b|, with its bottom left corner at |(h,v)|. Then
1)	set |h:=h+b|. If either |a<=0| or |b<=0|, nothing should be typeset. Note
1)	that if |b<0|, the value of |h| will decrease even though nothing else happens.
**** File 2) DVITYP.WEB[PAS,DEK]/5P/109L
2)	\yskip\hang|set_rule| 132 |a[4]| |b[4]|. Typeset a solid black rectangle
2)	of height |a| and width |b|, with its bottom left corner at |(h,v)|. Then
2)	set |h←h+b|. If either |a≤0| or |b≤0|, nothing should be typeset. Note
2)	that if |b<0|, the value of |h| will decrease even though nothing else happens.
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/446L
1)	the |rule←pixels| subroutine below.
1)	\yskip\hang|put1| 133 |c[1]|. Typeset character number@@|c| from font@@|f|
**** File 2) DVITYP.WEB[PAS,DEK]/5P/115L
2)	the |rule_pixels| subroutine below.
2)	\yskip\hang|put1| 133 |c[1]|. Typeset character number@@|c| from font@@|f|
***************
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5



**** File 1) DVITYP.WEB[WEB,ALS]/1P/459L
1)	\yskip\hang|put←rule| 137 |a[4]| |b[4]|. Same as |set←rule|, except that
1)	|h| is not changed.
**** File 2) DVITYP.WEB[PAS,DEK]/5P/128L
2)	\yskip\hang|put_rule| 137 |a[4]| |b[4]|. Same as |set_rule|, except that
2)	|h| is not changed.
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/466L
1)	\yskip\hang|bop| 139 $c←0[4]$ $c←1[4]$ $\ldots$ $c←9[4]$ $p[4]$. Beginning
1)	of a page: Set |(h,v,w,x,y,z):=(0,0,0,0,0,0)| and set the stack empty. Set
1)	the current font |f| to an undefined value.  The ten $c←i$ parameters can
1)	be used to identify pages, if a user wants to print only part of a \.{DVI}
**** File 2) DVITYP.WEB[PAS,DEK]/5P/135L
2)	\yskip\hang|bop| 139 $c↓0[4]$ $c↓1[4]$ $\ldots$ $c↓9[4]$ $p[4]$. Beginning
2)	of a page: Set |(h,v,w,x,y,z)←(0,0,0,0,0,0)| and set the stack empty. Set
2)	the current font |f| to an undefined value.  The ten $c↓i$ parameters can
2)	be used to identify pages, if a user wants to print only part of a \.{DVI}
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/492L
1)	\yskip\hang|right1| 143 |b[1]|. Set |h:=h+b|, i.e., move right |b| units.
1)	The parameter is a signed number in two's complement notation, |-128<=b<128|;
1)	if |b<0|, the reference point actually moves left.
1)	\yskip\hang|right2| 144 |b[2]|. Same as |right1|, except that |b| is a
1)	two-byte quantity in the range |-32768<=b<32768|.
1)	\yskip\hang|right3| 145 |b[3]|. Same as |right1|, except that |b| is a
1)	three-byte quantity in the range |@t$-2↑{23}$@><=b<@t$2↑{23}$@>|.
1)	\yskip\hang|right4| 146 |b[4]|. Same as |right1|, except that |b| is a
1)	four-byte quantity in the range |@t$-2↑{31}$@><=b<@t$2↑{31}$@>|.
1)	\yskip\hang|w0| 147. Set |h:=h+w|; i.e., move right |w| units. With luck,
1)	this parameterless command will usually suffice, because the same kind of motion
**** File 2) DVITYP.WEB[PAS,DEK]/5P/161L
2)	\yskip\hang|right1| 143 |b[1]|. Set |h←h+b|, i.e., move right |b| units.
2)	The parameter is a signed number in two's complement notation, |-128≤b<128|;
2)	if |b<0|, the reference point actually moves left.
2)	\yskip\hang|right2| 144 |b[2]|. Same as |right1|, except that |b| is a
2)	two-byte quantity in the range |-32768≤b<32768|.
2)	\yskip\hang|right3| 145 |b[3]|. Same as |right1|, except that |b| is a
2)	three-byte quantity in the range |@t$-2↑{23}$@>≤b<@t$2↑{23}$@>|.
2)	\yskip\hang|right4| 146 |b[4]|. Same as |right1|, except that |b| is a
2)	four-byte quantity in the range |@t$-2↑{31}$@>≤b<@t$2↑{31}$@>|.
2)	\yskip\hang|w0| 147. Set |h←h+w|; i.e., move right |w| units. With luck,
2)	this parameterless command will usually suffice, because the same kind of motion
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5

***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/510L
1)	\yskip\hang|w1| 148 |b[1]|. Set |w:=b| and |h:=h+b|. The value of |b| is a
1)	signed quantity in two's complement notation, |-128<=b<128|. This command
1)	changes the current |w|@@spacing and moves right by |b|.
1)	\yskip\hang|w2| 149 |b[2]|. Same as |w1|, but |b| is a two-byte-long
1)	parameter, |-32768<=b<32768|.
1)	\yskip\hang|w3| 150 |b[3]|. Same as |w1|, but |b| is a three-byte-long
1)	parameter, |@t$-2↑{23}$@><=b<@t$2↑{23}$@>|.
1)	\yskip\hang|w4| 151 |b[4]|. Same as |w1|, but |b| is a four-byte-long
1)	parameter, |@t$-2↑{31}$@><=b<@t$2↑{31}$@>|.
1)	\yskip\hang|x0| 152. Set |h:=h+x|; i.e., move right |x| units. The `|x|'
1)	commands are like the `|w|' commands except that they involve |x| instead
1)	of |w|.
1)	\yskip\hang|x1| 153 |b[1]|. Set |x:=b| and |h:=h+b|. The value of |b| is a
1)	signed quantity in two's complement notation, |-128<=b<128|. This command
1)	changes the current |x|@@spacing and moves right by |b|.
1)	\yskip\hang|x2| 154 |b[2]|. Same as |x1|, but |b| is a two-byte-long
1)	parameter, |-32768<=b<32768|.
1)	\yskip\hang|x3| 155 |b[3]|. Same as |x1|, but |b| is a three-byte-long
1)	parameter, |@t$-2↑{23}$@><=b<@t$2↑{23}$@>|.
1)	\yskip\hang|x4| 156 |b[4]|. Same as |x1|, but |b| is a four-byte-long
1)	parameter, |@t$-2↑{31}$@><=b<@t$2↑{31}$@>|.
1)	\yskip\hang|down1| 157 |a[1]|. Set |v:=v+a|, i.e., move down |a| units.
1)	The parameter is a signed number in two's complement notation, |-128<=a<128|;
1)	if |a<0|, the reference point actually moves up.
1)	\yskip\hang|down2| 158 |a[2]|. Same as |down1|, except that |a| is a
1)	two-byte quantity in the range |-32768<=a<32768|.
1)	\yskip\hang|down3| 159 |a[3]|. Same as |down1|, except that |a| is a
1)	three-byte quantity in the range |@t$-2↑{23}$@><=a<@t$2↑{23}$@>|.
1)	\yskip\hang|down4| 160 |a[4]|. Same as |down1|, except that |a| is a
1)	four-byte quantity in the range |@t$-2↑{31}$@><=a<@t$2↑{31}$@>|.
1)	\yskip\hang|y0| 161. Set |v:=v+y|; i.e., move down |y| units. With luck,
1)	this parameterless command will usually suffice, because the same kind of motion
**** File 2) DVITYP.WEB[PAS,DEK]/5P/179L
2)	\yskip\hang|w1| 148 |b[1]|. Set |w←b| and |h←h+b|. The value of |b| is a
2)	signed quantity in two's complement notation, |-128≤b<128|. This command
2)	changes the current |w|@@spacing and moves right by |b|.
2)	\yskip\hang|w2| 149 |b[2]|. Same as |w1|, but |b| is a two-byte-long
2)	parameter, |-32768≤b<32768|.
2)	\yskip\hang|w3| 150 |b[3]|. Same as |w1|, but |b| is a three-byte-long
2)	parameter, |@t$-2↑{23}$@>≤b<@t$2↑{23}$@>|.
2)	\yskip\hang|w4| 151 |b[4]|. Same as |w1|, but |b| is a four-byte-long
2)	parameter, |@t$-2↑{31}$@>≤b<@t$2↑{31}$@>|.
2)	\yskip\hang|x0| 152. Set |h←h+x|; i.e., move right |x| units. The `|x|'
2)	commands are like the `|w|' commands except that they involve |x| instead
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5

2)	of |w|.
2)	\yskip\hang|x1| 153 |b[1]|. Set |x←b| and |h←h+b|. The value of |b| is a
2)	signed quantity in two's complement notation, |-128≤b<128|. This command
2)	changes the current |x|@@spacing and moves right by |b|.
2)	\yskip\hang|x2| 154 |b[2]|. Same as |x1|, but |b| is a two-byte-long
2)	parameter, |-32768≤b<32768|.
2)	\yskip\hang|x3| 155 |b[3]|. Same as |x1|, but |b| is a three-byte-long
2)	parameter, |@t$-2↑{23}$@>≤b<@t$2↑{23}$@>|.
2)	\yskip\hang|x4| 156 |b[4]|. Same as |x1|, but |b| is a four-byte-long
2)	parameter, |@t$-2↑{31}$@>≤b<@t$2↑{31}$@>|.
2)	\yskip\hang|down1| 157 |a[1]|. Set |v←v+a|, i.e., move down |a| units.
2)	The parameter is a signed number in two's complement notation, |-128≤a<128|;
2)	if |a<0|, the reference point actually moves up.
2)	\yskip\hang|down2| 158 |a[2]|. Same as |down1|, except that |a| is a
2)	two-byte quantity in the range |-32768≤a<32768|.
2)	\yskip\hang|down3| 159 |a[3]|. Same as |down1|, except that |a| is a
2)	three-byte quantity in the range |@t$-2↑{23}$@>≤a<@t$2↑{23}$@>|.
2)	\yskip\hang|down4| 160 |a[4]|. Same as |down1|, except that |a| is a
2)	four-byte quantity in the range |@t$-2↑{31}$@>≤a<@t$2↑{31}$@>|.
2)	\yskip\hang|y0| 161. Set |v←v+y|; i.e., move down |y| units. With luck,
2)	this parameterless command will usually suffice, because the same kind of motion
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/558L
1)	\yskip\hang|y1| 162 |a[1]|. Set |y:=a| and |v:=v+a|. The value of |a| is a
1)	signed quantity in two's complement notation, |-128<=a<128|. This command
1)	changes the current |y|@@spacing and moves down by |a|.
1)	\yskip\hang|y2| 163 |a[2]|. Same as |y1|, but |a| is a two-byte-long
1)	parameter, |-32768<=a<32768|.
1)	\yskip\hang|y3| 164 |a[3]|. Same as |y1|, but |a| is a three-byte-long
1)	parameter, |@t$-2↑{23}$@><=a<@t$2↑{23}$@>|.
1)	\yskip\hang|y4| 165 |a[4]|. Same as |y1|, but |a| is a four-byte-long
1)	parameter, |@t$-2↑{31}$@><=a<@t$2↑{31}$@>|.
1)	\yskip\hang|z0| 166. Set |v:=v+z|; i.e., move down |z| units. The `|z|' commands
1)	are like the `|y|' commands except that they involve |z| instead of |y|.
1)	\yskip\hang|z1| 167 |a[1]|. Set |z:=a| and |v:=v+a|. The value of |a| is a
1)	signed quantity in two's complement notation, |-128<=a<128|. This command
1)	changes the current |z|@@spacing and moves down βy |a|.
1)	\yskip\hang|z2| 168 |a[2]|. Same as |z1|, but |a| is a two-byte-long
1)	parameter, |-32768<=a<32768|.
1)	\yskip\hang|z3| 169 |a[3]|. Same as |z1|, but |a| is a three-byte-long
1)	parameter, |@t$-2↑{23}$@><=a<@t$2↑{23}$@>|.
1)	\yskip\hang|z4| 170 |a[4]|. Same as |z1|, but |a| is a four-byte-long
1)	parameter, |@t$-2↑{31}$@><=a<@t$2↑{31}$@>|.
1)	\yskip\hang|fnt←num←0| 171. Set |f:=0|. Font 0 must previously have been
1)	defined by a \\{fnt\←def} instruction, as explained below.
1)	\yskip\hang|fnt←num←1| through |fnt←num←63| (opcodes 172 to 234). Set
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5

1)	|f:=1|, $\ldotss$, |f:=63|, respectively.
1)	\yskip\hang|fnt1| 235 |k[1]|. Set |f:=k|. \TeX82 uses this command for font
1)	numbers in the range |64<=k<256|.
1)	\yskip\hang|fnt2| 236 |k[2]|. Same as |fnt1|, except that@@|k| is two
1)	bytes long, so it is in the range |0<=k<65536|. \TeX82 never generates this
1)	command, but large font numbers may prove useful for specifications of
**** File 2) DVITYP.WEB[PAS,DEK]/5P/227L
2)	\yskip\hang|y1| 162 |a[1]|. Set |y←a| and |v←v+a|. The value of |a| is a
2)	signed quantity in two's complement notation, |-128≤a<128|. This command
2)	changes the current |y|@@spacing and moves down by |a|.
2)	\yskip\hang|y2| 163 |a[2]|. Same as |y1|, but |a| is a two-byte-long
2)	parameter, |-32768≤a<32768|.
2)	\yskip\hang|y3| 164 |a[3]|. Same as |y1|, but |a| is a three-byte-long
2)	parameter, |@t$-2↑{23}$@>≤a<@t$2↑{23}$@>|.
2)	\yskip\hang|y4| 165 |a[4]|. Same as |y1|, but |a| is a four-byte-long
2)	parameter, |@t$-2↑{31}$@>≤a<@t$2↑{31}$@>|.
2)	\yskip\hang|z0| 166. Set |v←v+z|; i.e., move down |z| units. The `|z|' commands
2)	are like the `|y|' commands except that they involve |z| instead of |y|.
2)	\yskip\hang|z1| 167 |a[1]|. Set |z←a| and |v←v+a|. The value of |a| is a
2)	signed quantity in two's complement notation, |-128≤a<128|. This command
2)	changes the current |z|@@spacing and moves down by |a|.
2)	\yskip\hang|z2| 168 |a[2]|. Same as |z1|, but |a| is a two-byte-long
2)	parameter, |-32768≤a<32768|.
2)	\yskip\hang|z3| 169 |a[3]|. Same as |z1|, but |a| is a three-byte-long
2)	parameter, |@t$-2↑{23}$@>≤a<@t$2↑{23}$@>|.
2)	\yskip\hang|z4| 170 |a[4]|. Same as |z1|, but |a| is a four-byte-long
2)	parameter, |@t$-2↑{31}$@>≤a<@t$2↑{31}$@>|.
2)	\yskip\hang|fnt_num_0| 171. Set |f←0|. Font 0 must previously have been
2)	defined by a \\{fnt\_def} instruction, as explained below.
2)	\yskip\hang|fnt_num_1| through |fnt_num_63| (opcodes 172 to 234). Set
2)	|f←1|, $\ldotss$, |f←63|, respectively.
2)	\yskip\hang|fnt1| 235 |k[1]|. Set |f←k|. \TeX82 uses this command for font
2)	numbers in the range |64≤k<256|.
2)	\yskip\hang|fnt2| 236 |k[2]|. Same as |fnt1|, except that@@|k| is two
2)	bytes long, so it is in the range |0≤k<65536|. \TeX82 never generates this
2)	command, but large font numbers may prove useful for specifications of
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/610L
1)	programs are being used. \TeX82 generates |xxx1| when a normal \.{\\xsend}
1)	appears, setting |k| to the number of bytes being sent. It is recommended that
1)	|x| be a string having the form of a keyword followed by possible parameters
1)	relevant to that keyword.
1)	\yskip\hang|xxx2| 240 |k[2]| |x[k]|. Like |xxx1|, but |0<=k<65536|.
1)	\yskip\hang|xxx3| 241 |k[3]| |x[k]|. Like |xxx1|, but |0<=k<@t$2↑{24}$@>|.
1)	\yskip\hang|xxx4| 242 |k[4]| |x[k]|. Like |xxx1|, but |k| can be ridiculously
1)	large. \TeX82 uses |xxx4| when |xxx1| would be incorrect.
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5

1)	\yskip\hang|fnt←def1| 243 |k[1]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
1)	Define font |k|, where |0<=k<63|; font definitions will be explained shortly.
1)	\yskip\hang|fnt←def2| 244 |k[2]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
1)	Define font |k|, where |0<=k<65536|.
1)	\yskip\hang|fnt←def3| 245 |k[3]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
1)	Define font |k|, where |0<=k<@t$2↑{24}$@>|.
1)	\yskip\hang|fnt←def4| 246 |k[4]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
1)	Define font |k|, where |@t$-2↑{31}$@><=k<@t$2↑{30}$@>|.
1)	\yskip\hang|pre| 247 |i[1]| |num[4]| |den[4]| |mag[4]| |k[1]| |x[k]|.
**** File 2) DVITYP.WEB[PAS,DEK]/5P/279L
2)	programs are being used. \TeX82 generates |xxx1| when a short enough
2)	\.{\\special} appears, setting |k| to the number of bytes being sent. It
2)	is recommended that |x| be a string having the form of a keyword followed
2)	by possible parameters relevant to that keyword.
2)	\yskip\hang|xxx2| 240 |k[2]| |x[k]|. Like |xxx1|, but |0≤k<65536|.
2)	\yskip\hang|xxx3| 241 |k[3]| |x[k]|. Like |xxx1|, but |0≤k<@t$2↑{24}$@>|.
2)	\yskip\hang|xxx4| 242 |k[4]| |x[k]|. Like |xxx1|, but |k| can be ridiculously
2)	large. \TeX82 uses |xxx4| when |xxx1| would be incorrect.
2)	\yskip\hang|fnt_def1| 243 |k[1]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
2)	Define font |k|, where |0≤k<63|; font definitions will be explained shortly.
2)	\yskip\hang|fnt_def2| 244 |k[2]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
2)	Define font |k|, where |0≤k<65536|.
2)	\yskip\hang|fnt_def3| 245 |k[3]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
2)	Define font |k|, where |0≤k<@t$2↑{24}$@>|.
2)	\yskip\hang|fnt_def4| 246 |k[4]| |c[4]| |s[4]| |d[4]| |a[1]| |l[1]| |n[a+l]|.
2)	Define font |k|, where |@t$-2↑{31}$@>≤k<@t$2↑{30}$@>|.
2)	\yskip\hang|pre| 247 |i[1]| |num[4]| |den[4]| |mag[4]| |k[1]| |x[k]|.
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/640L
1)	\yskip\hang|post←post| 249. Ending of the postamble, see below.
1)	\yskip\noindent Commands 250--255 are undefined at the present time.
1)	@ @d set←char←0=0 {typeset character 0 and move right}
1)	@d set1=128 {typeset a character and move right}
1)	@d set←rule=132 {typeset a rule and move right}
1)	@d put1=133 {typeset a character}
1)	@d put←rule=137 {typeset a rule}
1)	@d nop=138 {no operation}
**** File 2) DVITYP.WEB[PAS,DEK]/5P/309L
2)	\yskip\hang|post_post| 249. Ending of the postamble, see below.
2)	\yskip\noindent Commands 250--255 are undefined at the present time.
2)	@ @d set_char_0=0 {typeset character 0 and move right}
2)	@d set1=128 {typeset a character and move right}
2)	@d set_rule=132 {typeset a rule and move right}
2)	@d put1=133 {typeset a character}
2)	@d put_rule=137 {typeset a rule}
2)	@d nop=138 {no operation}
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5

***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/664L
1)	@d fnt←num←0=171 {set current font to 0}
1)	@d fnt1=235 {set current font}
**** File 2) DVITYP.WEB[PAS,DEK]/5P/333L
2)	@d fnt_num_0=171 {set current font to 0}
2)	@d fnt1=235 {set current font}
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/668L
1)	@d fnt←def1=243 {define the meaning of a font number}
1)	@d pre=247 {preamble}
1)	@d post=248 {postamble beginning}
1)	@d post←post=249 {postamble ending}
1)	@d undefined←commands==250,251,252,253,254,255
1)	@ The preamble contains basic information about the file as a whole. As
**** File 2) DVITYP.WEB[PAS,DEK]/5P/337L
2)	@d fnt_def1=243 {define the meaning of a font number}
2)	@d pre=247 {preamble}
2)	@d post=248 {postamble beginning}
2)	@d post_post=249 {postamble ending}
2)	@d undefined_commands==250,251,252,253,254,255
2)	@ The preamble contains basic information about the file as a whole. As
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/700L
1)	interpreted further. The length of comment |x| is |k|, where |0<=k<256|.
1)	@d id←byte=2 {identifies the kind of \.{DVI} files described here}
1)	@ Font definitions for a given font number |k| contain further parameters
**** File 2) DVITYP.WEB[PAS,DEK]/5P/369L
2)	interpreted further. The length of comment |x| is |k|, where |0≤k<256|.
2)	@d id_byte=2 {identifies the kind of \.{DVI} files described here}
2)	@ Font definitions for a given font number |k| contain further parameters
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/739L
1)	  |post| |p[4]| |num[4]| |den[4]| |mag[4]| |l[4]| |u[4]| |s[2]| |t[2]|\cr
1)	  $\langle\,$font definitions$\,\rangle$\cr
1)	  |post←post| |q[4]| |i[1]| 223's|[>=4]|\cr}}$$
1)	Here |p| is a pointer to the final |bop| in the file. The next three
**** File 2) DVITYP.WEB[PAS,DEK]/5P/408L
2)		|post| |p[4]| |num[4]| |den[4]| |mag[4]| |l[4]| |u[4]| |s[2]| |t[2]|\cr
2)		$\langle\,$font definitions$\,\rangle$\cr
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,5

2)		|post_post| |q[4]| |i[1]| 223's|[≥4]|\cr}}$$
2)	Here |p| is a pointer to the final |bop| in the file. The next three
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/756L
1)	\\{fnt\←def} commands as described above, possibly interspersed with |nop|
1)	commands. Each font number that is used in the \.{DVI} file must be defined
**** File 2) DVITYP.WEB[PAS,DEK]/5P/425L
2)	\\{fnt\_def} commands as described above, possibly interspersed with |nop|
2)	commands. Each font number that is used in the \.{DVI} file must be defined
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/761L
1)	@ The last part of the postamble, following the |post←post| byte that
1)	signifies the end of the font definitions, contains |q|, a pointer to the
1)	|post| command that started the postamble.  An identification byte, |i|,
1)	comes nest; this currently equals@@2, as in the preamble.
1)	The |i| byte is followed by four or more bytes that are all equal to
**** File 2) DVITYP.WEB[PAS,DEK]/5P/430L
2)	@ The last part of the postamble, following the |post_post| byte that
2)	signifies the end of the font definitions, contains |q|, a pointer to the
2)	|post| command that started the postamble.  An identification byte, |i|,
2)	comes next; this currently equals@@2, as in the preamble.
2)	The |i| byte is followed by four or more bytes that are all equal to
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/794L
1)	\PASCAL\ if |random←reading| is defined to be |false|.
1)	@* Input from binary files.
**** File 2) DVITYP.WEB[PAS,DEK]/5P/463L
2)	\PASCAL\ if |random_reading| is defined to be |false|.
2)	@* Input from binary files.
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/815L
1)	|if x>=0 then a:=x div @'100000000|\cr
1)	|else begin x:=(x+@'10000000000)+@'10000000000; a:=x div @'100000000+128;|\cr
1)	\quad|end|\cr
1)	|x:=x mod @'100000000;|\cr
1)	|b:=x div @'200000; x:=x mod @'200000;|\cr
1)	|c:=x div @'400; d:=x mod @'400;|\cr}}$$
1)	The four bytes are then kept in a buffer and output one by one. (On 36-bit
**** File 2) DVITYP.WEB[PAS,DEK]/6P/20L
2)	|if x≥0 then a←x div @'100000000|\cr
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,6

2)	|else begin x←(x+@'10000000000)+@'10000000000; a←x div @'100000000+128;|\cr
2)	\quad|end|\cr
2)	|x←x mod @'100000000;|\cr
2)	|b←x div @'200000; x←x mod @'200000;|\cr
2)	|c←x div @'400; d←x mod @'400;|\cr}}$$
2)	The four bytes are then kept in a buffer and output one by one. (On 36-bit
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/833L
1)	@!eight←bits=0..255; {unsigned one-byte quantity}
1)	@!byte←file=packed file of eight←bits; {files that contain binary data}
1)	@ The program deals with two binary file variables: |dvi←file| is the main
1)	input file that we are translating into symbolic form, and |tfm←file| is
1)	the current font metric file from which character-width information is
**** File 2) DVITYP.WEB[PAS,DEK]/6P/38L
2)	@!eight_bits=0..255; {unsigned one-byte quantity}
2)	@!byte_file=packed file of eight_bits; {files that contain binary data}
2)	@ The program deals with two binary file variables: |dvi_file| is the main
2)	input file that we are translating into symbolic form, and |tfm_file| is
2)	the current font metric file from which character-width information is
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/842L
1)	@!dvi←file:byte←file; {the stuff we are \.{DVI}typing}
1)	@!tfm←file:byte←file; {a font metric file}
1)	@ To prepare these files for input, we |reset| them. An extension of
1)	\PASCAL\ is needed in the case of |tfm←file|, since we want to associate
1)	it with external files whose names are specified dynamically (i.e., not
**** File 2) DVITYP.WEB[PAS,DEK]/6P/47L
2)	@!dvi_file:byte_file; {the stuff we are \.{DVI}typing}
2)	@!tfm_file:byte_file; {a font metric file}
2)	@ To prepare these files for input, we |reset| them. An extension of
2)	\PASCAL\ is needed in the case of |tfm_file|, since we want to associate
2)	it with external files whose names are specified dynamically (i.e., not
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/854L
1)	@p procedure open←dvi←file; {prepares to read packed bytes in |dvi←file|}
1)	begin reset(dvi←file);
1)	cur←loc:=0;
1)	end;
1)	@#
1)	procedure open←tfm←file; {prepares to read packed bytes in |tfm←file|}
1)	begin reset(tfm←file,cur←name);
1)	end;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,6

1)	@ If you looked carefully at the preceding code, you probably asked,
1)	``What are |cur←loc| and |cur←name|?'' Good question. They're global
1)	variables: |cur←loc| is the number of the byte about to be read next from
1)	|dvi←file|, and |cur←name| is a string variable that will be set to the
1)	current font metric file name before |open←tfm←file| is called.
1)	@<Glob...@>=
1)	@!cur←loc:integer; {where we are about to look, in |dvi←file|}
1)	@!cur←name:packed array[1..name←length] of char; {external name,
1)	  with no lower case letters}
1)	@ It turns out to be convenient to read four bytes at a time, when we are
**** File 2) DVITYP.WEB[PAS,DEK]/6P/59L
2)	@p procedure open_dvi_file; {prepares to read packed bytes in |dvi_file|}
2)	begin reset(dvi_file);
2)	cur_loc←0;
2)	end;
2)	@#
2)	procedure open_tfm_file; {prepares to read packed bytes in |tfm_file|}
2)	begin reset(tfm_file,cur_name);
2)	end;
2)	@ If you looked carefully at the preceding code, you probably asked,
2)	``What are |cur_loc| and |cur_name|?'' Good question. They're global
2)	variables: |cur_loc| is the number of the byte about to be read next from
2)	|dvi_file|, and |cur_name| is a string variable that will be set to the
2)	current font metric file name before |open_tfm_file| is called.
2)	@<Glob...@>=
2)	@!cur_loc:integer; {where we are about to look, in |dvi_file|}
2)	@!cur_name:packed array[1..name_length] of char; {external name,
2)		with no lower case letters}
2)	@ It turns out to be convenient to read four bytes at a time, when we are
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/880L
1)	@!b0,@!b1,@!b2,@!b3: eight←bits; {four bytes input at once}
1)	@ The |read←tfm←word| procedure sets |b0| through |b3| to the next
1)	four bytes in the current \.{TFM} file.
1)	@↑system dependencies@>
1)	@p procedure read←tfm←word;
1)	begin read(tfm←file,b0); read(tfm←file,b1);
1)	read(tfm←file,b2); read(tfm←file,b3);
1)	end;
1)	@ We shall use another set of simple functions to read the next byte or
1)	bytes from |dvi←file|. There are seven possibilities, each of which is
1)	treated as a separate function in order to minimize the overhead for
**** File 2) DVITYP.WEB[PAS,DEK]/6P/85L
2)	@!b0,@!b1,@!b2,@!b3: eight_bits; {four bytes input at once}
2)	@ The |read_tfm_word| procedure sets |b0| through |b3| to the next
2)	four bytes in the current \.{TFM} file.
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,6

2)	@↑system dependencies@>
2)	@p procedure read_tfm_word;
2)	begin read(tfm_file,b0); read(tfm_file,b1);
2)	read(tfm_file,b2); read(tfm_file,b3);
2)	end;
2)	@ We shall use another set of simple functions to read the next byte or
2)	bytes from |dvi_file|. There are seven possibilities, each of which is
2)	treated as a separate function in order to minimize the overhead for
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/897L
1)	@p function get←byte:integer; {returns the next byte, unsigned}
1)	var b:eight←bits;
1)	begin if eof(dvi←file) then get←byte:=0
1)	else  begin read(dvi←file,b); incr(cur←loc); get←byte:=b;
1)	  end;
1)	end;
1)	@#
1)	function signed←byte:integer; {returns the next byte, signed}
1)	var b:eight←bits;
1)	begin read(dvi←file,b); incr(cur←loc);
1)	if b<128 then signed←byte:=b @+ else signed←byte:=b-256;
1)	end;
1)	@#
1)	function get←two←bytes:integer; {returns the next two bytes, unsigned}
1)	var a,@!b:eight←bits;
1)	begin read(dvi←file,a); read(dvi←file,b);
1)	cur←loc:=cur←loc+2;
1)	get←two←bytes:=a*256+b;
1)	end;
1)	@#
1)	function signed←pair:integer; {returns the next two bytes, signed}
1)	var a,@!b:eight←bits;
1)	begin read(dvi←file,a); read(dvi←file,b);
1)	cur←loc:=cur←loc+2;
1)	if a<128 then signed←pair:=a*256+b
1)	else signed←pair:=(a-256)*256+b;
1)	end;
1)	@#
1)	function get←three←bytes:integer; {returns the next three bytes, unsigned}
1)	var a,@!b,@!c:eight←bits;
1)	begin read(dvi←file,a); read(dvi←file,b); read(dvi←file,c);
1)	cur←loc:=cur←loc+3;
1)	get←three←bytes:=(a*256+b)*256+c;
1)	end;
1)	@#
1)	function signed←trio:integer; {returns the next three bytes, signed}
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,6

1)	var a,@!b,@!c:eight←bits;
1)	begin read(dvi←file,a); read(dvi←file,b); read(dvi←file,c);
1)	cur←loc:=cur←loc+3;
1)	if a<128 then signed←trio:=(a*256+b)*256+c
1)	else signed←trio:=((a-256)*256+b)*256+c;
1)	end;
1)	@#
1)	function signed←quad:integer; {returns the next four bytes, signed}
1)	var a,@!b,@!c,@!d:eight←bits;
1)	begin read(dvi←file,a); read(dvi←file,b); read(dvi←file,c); read(dvi←file,d);
1)	cur←loc:=cur←loc+4;
1)	if a<128 then signed←quad:=((a*256+b)*256+c)*256+d
1)	else signed←quad:=(((a-256)*256+b)*256+c)*256+d;
1)	end;
1)	@ Finally we come to the routines that are used only if |random←reading| is
1)	|true|. The driver program below needs two such routines: |dvi←length| should
1)	compute the total number of bytes in |dvi←file|, possibly also
1)	causing |eof(dvi←file)| to be true; and |move←to←byte(n)|
1)	should position |dvi←file| so that the next |get←byte| will read byte |n|,
1)	starting with |n=0| for the first byte in the file.
**** File 2) DVITYP.WEB[PAS,DEK]/6P/102L
2)	@p function get_byte:integer; {returns the next byte, unsigned}
2)	var b:eight_bits;
2)	begin if eof(dvi_file) then get_byte←0
2)	else	begin read(dvi_file,b); incr(cur_loc); get_byte←b;
2)		end;
2)	end;
2)	@#
2)	function signed_byte:integer; {returns the next byte, signed}
2)	var b:eight_bits;
2)	begin read(dvi_file,b); incr(cur_loc);
2)	if b<128 then signed_byte←b @+ else signed_byte←b-256;
2)	end;
2)	@#
2)	function get_two_bytes:integer; {returns the next two bytes, unsigned}
2)	var a,@!b:eight_bits;
2)	begin read(dvi_file,a); read(dvi_file,b);
2)	cur_loc←cur_loc+2;
2)	get_two_bytes←a*256+b;
2)	end;
2)	@#
2)	function signed_pair:integer; {returns the next two bytes, signed}
2)	var a,@!b:eight_bits;
2)	begin read(dvi_file,a); read(dvi_file,b);
2)	cur_loc←cur_loc+2;
2)	if a<128 then signed_pair←a*256+b
2)	else signed_pair←(a-256)*256+b;
2)	end;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,6

2)	@#
2)	function get_three_bytes:integer; {returns the next three bytes, unsigned}
2)	var a,@!b,@!c:eight_bits;
2)	begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c);
2)	cur_loc←cur_loc+3;
2)	get_three_bytes←(a*256+b)*256+c;
2)	end;
2)	@#
2)	function signed_trio:integer; {returns the next three bytes, signed}
2)	var a,@!b,@!c:eight_bits;
2)	begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c);
2)	cur_loc←cur_loc+3;
2)	if a<128 then signed_trio←(a*256+b)*256+c
2)	else signed_trio←((a-256)*256+b)*256+c;
2)	end;
2)	@#
2)	function signed_quad:integer; {returns the next four bytes, signed}
2)	var a,@!b,@!c,@!d:eight_bits;
2)	begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); read(dvi_file,d);
2)	cur_loc←cur_loc+4;
2)	if a<128 then signed_quad←((a*256+b)*256+c)*256+d
2)	else signed_quad←(((a-256)*256+b)*256+c)*256+d;
2)	end;
2)	@ Finally we come to the routines that are used only if |random_reading| is
2)	|true|. The driver program below needs two such routines: |dvi_length| should
2)	compute the total number of bytes in |dvi_file|, possibly also
2)	causing |eof(dvi_file)| to be true; and |move_to_byte(n)|
2)	should position |dvi_file| so that the next |get_byte| will read byte |n|,
2)	starting with |n=0| for the first byte in the file.
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/957L
1)	here in terms of two assumed system routines called |set←pos| and |cur←pos|.
1)	The call |set←pos(f,n)| moves to item |n| in file |f|, unless |n| is
1)	negative or larger than the total number of items in |f|; in the latter
1)	case, |set←pos(f,n)| moves to the end of file |f|.
1)	The call |cur←pos(f)| gives the total number of items in |f|, if
1)	|eof(f)| is true; we use |cur←pos| only in such a situation.
1)	@p function dvi←length:integer;
1)	begin set←pos(dvi←file,-1); dvi←length:=cur←pos(dvi←file);
1)	end;
1)	@#
1)	procedure move←to←byte(n:integer);
1)	begin set←pos(dvi←file,n); cur←loc:=n;
1)	end;
**** File 2) DVITYP.WEB[PAS,DEK]/6P/162L
2)	here in terms of two assumed system routines called |set_pos| and |cur_pos|.
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,6

2)	The call |set_pos(f,n)| moves to item |n| in file |f|, unless |n| is
2)	negative or larger than the total number of items in |f|; in the latter
2)	case, |set_pos(f,n)| moves to the end of file |f|.
2)	The call |cur_pos(f)| gives the total number of items in |f|, if
2)	|eof(f)| is true; we use |cur_pos| only in such a situation.
2)	@p function dvi_length:integer;
2)	begin set_pos(dvi_file,-1); dvi_length←cur_pos(dvi_file);
2)	end;
2)	@#
2)	procedure move_to_byte(n:integer);
2)	begin set_pos(dvi_file,n); cur_loc←n;
2)	end;
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/976L
1)	in \\{set\←char} commands. Therefore \.{DVItype} looks at the font metric
1)	(\.{TFM}) files for the fonts that are involved.
**** File 2) DVITYP.WEB[PAS,DEK]/7P/5L
2)	in \\{set\_char} commands. Therefore \.{DVItype} looks at the font metric
2)	(\.{TFM}) files for the fonts that are involved.
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/997L
1)	an internal number |f|, where |0<=f<nf|; the external number of this font,
1)	i.e., its font identification number in the \.{DVI} file, is
1)	|font←num[f]|, and the external name of this font is the string that
1)	occupies positions |font←name[f]| through |font←name[f+1]-1| of the array
1)	|names|. The latter array consists of |ascii←code| characters, and
1)	|font←name[nf]| is its first unoccupied position.  A horizontal motion
1)	less than |font←space[f]| will be treated as a `kern' that is not
1)	indicated in the printouts that \.{DVItype} produces between brackets. The
1)	legal characters run from |font←bc[f]| to |font←ec[f]|, inclusive; more
1)	precisely, a given character |c| is valid in font |f| if and only if
1)	|font←bc[f]<=c<=font←ec[f]| and |char←width(f)(c)<>invalid←width|.
1)	(Exception: If |font←ec[f]=256|, all characters |c>=256| are valid and have
1)	the same width |char←width(f)(256)|.)
1)	@↑oriental characters@>@↑Chinese characters@>@↑Japanese characters@>
1)	Finally, |char←width(f)(c)=width[width←base[f]+c]|, and |width←ptr| is the
1)	first unused position of the |width| array.
1)	@d char←width←end(#)==#]
1)	@d char←width(#)==width[width←base[#]+char←width←end
1)	@d invalid←width==@'17777777777
1)	@<Glob...@>=
1)	@!font←num:array [0..max←fonts] of integer; {external font numbers}
1)	@!font←name:array [0..max←fonts] of 0..name←size; {starting positions
1)	  of external font names}
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,7

1)	@!names:array [0..name←size] of ascii←code; {characters of names}
1)	@!font←check←sum:array [0..max←fonts] of integer; {check sums}
1)	@!font←scaled←size:array [0..max←fonts] of integer; {scale factors}
1)	@!font←design←size:array [0..max←fonts] of integer; {design sizes}
1)	@!font←space:array [0..max←fonts] of integer; {boundary between ``small''
1)	  and ``large'' spaces}
1)	@!font←bc:array [0..max←fonts] of integer; {beginning characters in fonts}
1)	@!font←ec:array [0..max←fonts] of integer; {ending characters in fonts}
1)	@!width←base:array [0..max←fonts] of integer; {index into |width| table}
1)	@!width:array [0..max←widths] of integer; {character widths, in \.{DVI} units}
1)	@!nf:0..max←fonts; {the number of known fonts}
1)	@!width←ptr:0..max←widths; {the number of known character widths}
1)	@ @<Set init...@>=
1)	nf:=0; width←ptr:=0; font←name[0]:=0;
1)	@ It is, of course, a simple matter to print the name of a given font.
1)	@p procedure print←font(@!f:integer); {|f| is an internal font number}
1)	var k:0..name←size; {index into |names|}
1)	begin if f=nf then print('UNDEFINED!')
1)	@.UNDEFINED@>
1)	else  begin for k:=font←name[f] to font←name[f+1]-1 do
1)	    print(xchr[names[k]]);
1)	  end;
1)	end;
1)	@ An auxiliary array |in←width| is used to hold the widths as they are
1)	input. The global variable |tfm←check←sum| is set to the check sum that
1)	appears in the current \.{TFM} file.
1)	@<Glob...@>=
1)	@!in←width:array[0..255] of integer; {\.{TFM} width data in \.{DVI} units}
1)	@!tfm←check←sum:integer; {check sum found in |tfm←file|}
1)	@ Here is a procedure that absorbs the necessary information from a
**** File 2) DVITYP.WEB[PAS,DEK]/7P/26L
2)	an internal number |f|, where |0≤f<nf|; the external number of this font,
2)	i.e., its font identification number in the \.{DVI} file, is
2)	|font_num[f]|, and the external name of this font is the string that
2)	occupies positions |font_name[f]| through |font_name[f+1]-1| of the array
2)	|names|. The latter array consists of |ascii_code| characters, and
2)	|font_name[nf]| is its first unoccupied position.  A horizontal motion
2)	less than |font_space[f]| will be treated as a `kern' that is not
2)	indicated in the printouts that \.{DVItype} produces between brackets. The
2)	legal characters run from |font_bc[f]| to |font_ec[f]|, inclusive; more
2)	precisely, a given character |c| is valid in font |f| if and only if
2)	|font_bc[f]≤c≤font_ec[f]| and |char_width(f)(c)≠invalid_width|.
2)	(Exception: If |font_ec[f]=256|, all characters |c≥256| are valid and have
2)	the same width |char_width(f)(256)|.)
2)	@↑oriental characters@>@↑Chinese characters@>@↑Japanese characters@>
2)	Finally, |char_width(f)(c)=width[width_base[f]+c]|, and |width_ptr| is the
2)	first unused position of the |width| array.
2)	@d char_width_end(#)==#]
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,7

2)	@d char_width(#)==width[width_base[#]+char_width_end
2)	@d invalid_width==@'17777777777
2)	@<Glob...@>=
2)	@!font_num:array [0..max_fonts] of integer; {external font numbers}
2)	@!font_name:array [0..max_fonts] of 0..name_size; {starting positions
2)		of external font names}
2)	@!names:array [0..name_size] of ascii_code; {characters of names}
2)	@!font_check_sum:array [0..max_fonts] of integer; {check sums}
2)	@!font_scaled_size:array [0..max_fonts] of integer; {scale factors}
2)	@!font_design_size:array [0..max_fonts] of integer; {design sizes}
2)	@!font_space:array [0..max_fonts] of integer; {boundary between ``small''
2)		and ``large'' spaces}
2)	@!font_bc:array [0..max_fonts] of integer; {beginning characters in fonts}
2)	@!font_ec:array [0..max_fonts] of integer; {ending characters in fonts}
2)	@!width_base:array [0..max_fonts] of integer; {index into |width| table}
2)	@!width:array [0..max_widths] of integer; {character widths, in \.{DVI} units}
2)	@!nf:0..max_fonts; {the number of known fonts}
2)	@!width_ptr:0..max_widths; {the number of known character widths}
2)	@ @<Set init...@>=
2)	nf←0; width_ptr←0; font_name[0]←0;
2)	@ It is, of course, a simple matter to print the name of a given font.
2)	@p procedure print_font(@!f:integer); {|f| is an internal font number}
2)	var k:0..name_size; {index into |names|}
2)	begin if f=nf then print('UNDEFINED!')
2)	@.UNDEFINED@>
2)	else	begin for k←font_name[f] to font_name[f+1]-1 do
2)			print(xchr[names[k]]);
2)		end;
2)	end;
2)	@ An auxiliary array |in_width| is used to hold the widths as they are
2)	input. The global variable |tfm_check_sum| is set to the check sum that
2)	appears in the current \.{TFM} file.
2)	@<Glob...@>=
2)	@!in_width:array[0..255] of integer; {\.{TFM} width data in \.{DVI} units}
2)	@!tfm_check_sum:integer; {check sum found in |tfm_file|}
2)	@ Here is a procedure that absorbs the necessary information from a
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1072L
1)	@p function in←TFM(@!z:integer):boolean; {input \.{TFM} data or return |false|}
1)	label 9997, {go here when the format is bad}
1)	  9998,  {go here when the information cannot be loaded}
1)	  9999;  {go here to exit}
1)	var k:integer; {index for loops}
**** File 2) DVITYP.WEB[PAS,DEK]/7P/101L
2)	@p function in_TFM(@!z:integer):boolean; {input \.{TFM} data or return |false|}
2)	label 9997, {go here when the format is bad}
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,7

2)		9998,	{go here when the information cannot be loaded}
2)		9999;	{go here to exit}
2)	var k:integer; {index for loops}
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1079L
1)	@!wp:0..max←widths; {new value of |width←ptr| after successful input}
1)	@!alpha,@!beta:integer; {quantities used in the scaling computation}
**** File 2) DVITYP.WEB[PAS,DEK]/7P/108L
2)	@!wp:0..max_widths; {new value of |width_ptr| after successful input}
2)	@!alpha,@!beta:integer; {quantities used in the scaling computation}
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1083L
1)	@<Read and convert the width values, setting up the |in←width| table@>;
1)	@<Move the widths from |in←width| to |width|, and append |pixel←width| values@>;
1)	width←ptr:=wp; in←TFM:=true; goto 9999;
1)	9997: print←ln('---not loaded, TFM file is bad');
1)	@.TFM file is bad@>
1)	9998: in←TFM:=false;
1)	9999: end;
1)	@ @<Read past the header...@>=
1)	read←tfm←word; lh:=b2*256+b3;
1)	read←tfm←word; font←bc[nf]:=b0*256+b1; font←ec[nf]:=b2*256+b3;
1)	if font←ec[nf]<font←bc[nf] then font←bc[nf]:=font←ec[nf]+1;
1)	if width←ptr+font←ec[nf]-font←bc[nf]+1>max←widths then
1)	  begin print←ln('---not loaded, DVItype needs larger width table');
1)	@.DVItype needs larger...@>
1)	    goto 9998;
1)	  end;
1)	wp:=width←ptr+font←ec[nf]-font←bc[nf]+1;
1)	read←tfm←word; nw:=b0*256+b1;
1)	if (nw=0)or(nw>256) then goto 9997;
1)	for k:=1 to 3+lh do
1)	  begin if eof(tfm←file) then goto 9997;
1)	  read←tfm←word;
1)	  if k=4 then
1)	    if b0<128 then tfm←check←sum:=((b0*256+b1)*256+b2)*256+b3
1)	    else tfm←check←sum:=(((b0-256)*256+b1)*256+b2)*256+b3;
1)	  end;
1)	@ @<Store character-width indices...@>=
1)	if wp>0 then for k:=width←ptr to wp-1 do
1)	  begin read←tfm←word;
1)	  if b0>nw then goto 9997;
1)	  width[k]:=b0;
1)	  end;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,7

1)	@ The most important part of |in←TFM| is the width computation, which
1)	involves multiplying the relative widths in the \.{TFM} file by the
**** File 2) DVITYP.WEB[PAS,DEK]/7P/112L
2)	@<Read and convert the width values, setting up the |in_width| table@>;
2)	@<Move the widths from |in_width| to |width|, and append |pixel_width| values@>;
2)	width_ptr←wp; in_TFM←true; goto 9999;
2)	9997: print_ln('---not loaded, TFM file is bad');
2)	@.TFM file is bad@>
2)	9998: in_TFM←false;
2)	9999: end;
2)	@ @<Read past the header...@>=
2)	read_tfm_word; lh←b2*256+b3;
2)	read_tfm_word; font_bc[nf]←b0*256+b1; font_ec[nf]←b2*256+b3;
2)	if font_ec[nf]<font_bc[nf] then font_bc[nf]←font_ec[nf]+1;
2)	if width_ptr+font_ec[nf]-font_bc[nf]+1>max_widths then
2)		begin print_ln('---not loaded, DVItype needs larger width table');
2)	@.DVItype needs larger...@>
2)			goto 9998;
2)		end;
2)	wp←width_ptr+font_ec[nf]-font_bc[nf]+1;
2)	read_tfm_word; nw←b0*256+b1;
2)	if (nw=0)∨(nw>256) then goto 9997;
2)	for k←1 to 3+lh do
2)		begin if eof(tfm_file) then goto 9997;
2)		read_tfm_word;
2)		if k=4 then
2)			if b0<128 then tfm_check_sum←((b0*256+b1)*256+b2)*256+b3
2)			else tfm_check_sum←(((b0-256)*256+b1)*256+b2)*256+b3;
2)		end;
2)	@ @<Store character-width indices...@>=
2)	if wp>0 then for k←width_ptr to wp-1 do
2)		begin read_tfm_word;
2)		if b0>nw then goto 9997;
2)		width[k]←b0;
2)		end;
2)	@ The most important part of |in_TFM| is the width computation, which
2)	involves multiplying the relative widths in the \.{TFM} file by the
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1126L
1)	file appears as a four-byte quantity called a |fix←word|.  A |fix←word|
1)	whose respective bytes are $(a,b,c,d)$ represents the number
**** File 2) DVITYP.WEB[PAS,DEK]/7P/155L
2)	file appears as a four-byte quantity called a |fix_word|.  A |fix_word|
2)	whose respective bytes are $(a,b,c,d)$ represents the number
***************

  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,7


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1147L
1)	for k:=0 to nw-1 do
1)	  begin read←tfm←word;
1)	  in←width[k]:=(((((b3*z)div@'400)+(b2*z))div@'400)+(b1*z))div beta;
1)	  if b0>0 then if b0<255 then goto 9997
1)	    else in←width[k]:=in←width[k]-alpha;
1)	  end
1)	@ @<Replace |z|...@>=
1)	begin alpha:=16*z; beta:=16;
1)	while z>=@'40000000 do
1)	  begin z:=z div 2; beta:=beta div 2;
1)	  end;
1)	end
**** File 2) DVITYP.WEB[PAS,DEK]/7P/176L
2)	for k←0 to nw-1 do
2)		begin read_tfm_word;
2)		in_width[k]←(((((b3*z)div@'400)+(b2*z))div@'400)+(b1*z))div beta;
2)		if b0>0 then if b0<255 then goto 9997
2)			else in_width[k]←in_width[k]-alpha;
2)		end
2)	@ @<Replace |z|...@>=
2)	begin alpha←16*z; beta←16;
2)	while z≥@'40000000 do
2)		begin z←z div 2; beta←beta div 2;
2)		end;
2)	end
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1169L
1)	The |pixel←width| array contains this information; when |width[k]| is the
1)	device-independent width of some character in \.{DVI} units, |pixel←width[k]|
1)	is the corresponding width of that character in an actual font.
1)	The macro |char←pixel←width| is set up to be analogous to |char←width|.
1)	@d char←pixel←width(#)==pixel←width[width←base[#]+char←width←end
1)	@<Glob...@>=
1)	@!pixel←width:array[0..max←widths] of integer; {actual character widths,
1)	  in pixels}
1)	@!conv:real; {converts \.{DVI} units to pixels}
1)	@!true←conv:real; {converts unmagnified \.{DVI} units to pixels}
1)	@!numerator,@!denominator:integer; {stated conversion ratio}
**** File 2) DVITYP.WEB[PAS,DEK]/7P/198L
2)	The |pixel_width| array contains this information; when |width[k]| is the
2)	device-independent width of some character in \.{DVI} units, |pixel_width[k]|
2)	is the corresponding width of that character in an actual font.
2)	The macro |char_pixel_width| is set up to be analogous to |char_width|.
2)	@d char_pixel_width(#)==pixel_width[width_base[#]+char_width_end
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,7

2)	@<Glob...@>=
2)	@!pixel_width:array[0..max_widths] of integer; {actqal character widths,
2)		in pixels}
2)	@!conv:real; {converts \.{DVI} units to pixels}
2)	@!true_coNv:real; {converts unmagnified \.{DVI} units to pixels}
2)	@!numerator,@!denominator:integer; {stated conversion ratio}
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1196L
1)	@D pixel←round(#)==trunc(conv*(#)+0.5)
1)	@<Move the widths from |in←width| tk |width|, and append |pixel←width| values@>=
1)	width←base[nf]:=width←ptr-font←bc[nf];
1)	if wp>0 then for k:=width←ptr to wp-1 do
1)	  begin width[k]:=in←width[width[k]];
1)	  pixel←width[k]:=pixel←round(width[k]);
1)	  end
1)	@* Optional modes of output.
1)	\.{DVItype} will print different quantities of information based on some
1)	options that the user must specify: The |out←mode| level is set to one of
1)	four values (|errors←only|, |terse|, |verbose|, |the←works|), giving
1)	different degrees of output; and the typeout can be confined to a
**** File 2) DVITYP.WEB[PAS,DEK]/7P/225L
2)	@d pixel_round(#)==trunc(conv*(#)+0.5)
2)	@<Move the widths from |in_width| to |width|, and append |pixel_width| values@>=
2)	width_base[nf]←width_ptr-font_bc[nf];
2)	if wp>0 then for k←width_ptr to wp-1 do
2)		begin width[k]←in_width[width[k]];
2)		pixel_width[k]←pixel_round(width[k]);
2)		end
2)	@* Optional modes of output.
2)	\.{DVItype} will print different quantities of information based on some
2)	options that the user must specify: The |out_mode| level is set to one of
2)	four values (|errors_only|, |terse|, |verbose|, |the_works|), giving
2)	different degrees of output; and the typeout can be confined to a
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1231L
1)	default options (|out←mode=the←works|, starting page `\.*',
1)	|max←pages=1000000|, |resolution=240.0|, |new←mag=0|).  On other hand, the
1)	system-dependent routines that are needed are not complicated, so it will
**** File 2) DVITYP.WEB[PAS,DEK]/8P/27L
2)	default options (|out_mode=the_works|, starting page `\.*',
2)	|max_pages=1000000|, |resolution=240.0|, |new_mag=0|).  On other hand, the
2)	system-dependent routines that are needed are not complicated, so it will
***************

  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1237L
1)	@d errors←only=0 {value of |out←mode| when minimal printing occurs}
1)	@d terse=1 {value of |out←mode| for abbreviated output}
1)	@d verbose=2 {value of |out←mode| for detailed tracing}
1)	@d the←works=3 {|verbose|, plus check of postamble if |random←reading|}
1)	@<Glob...@>=
1)	@!out←mode:errors←only..the←works; {controls the amount of output}
1)	@!max←pages:integer; {at most this many |bop..eop| pages will be printed}
1)	@!resolution:real; {pixels per inch}
1)	@!new←mag:integer; {if positive, overrides the postamble's magnification}
1)	@ The starting page specification is recorded in two arrays called
1)	|start←count| and |start←there|. For example, `\.{1.*.-5}' is represented
1)	by |start←there[0]=true|, |start←count[0]=1|, |start←there[1]=false|,
1)	|start←there[2]=true|, |start←count[2]=-5|.
1)	We also set |start←vals=2|, to indicate that count 2 was the last one
1)	mentioned. The other values of |start←count| and |start←there| are not
1)	important, in this example.
1)	@<Glob...@>=
1)	@!start←count:array[0..9] of integer; {count values to select starting page}
1)	@!start←there:array[0..9] of boolean; {is the |start←count| value relevant?}
1)	@!start←vals:0..9; {the last count considered significant}
1)	@!count:array[0..9] of integer; {the count values on the current page}
1)	@ @<Set init...@>=
1)	out←mode:=the←works; max←pages:=1000000; start←vals:=0; start←there[0]:=false;
1)	@ Here is a simple subroutine that tests if the current page might be the
1)	starting page.
1)	@p function start←match:boolean; {does |count| match the starting spec?}
1)	var k:0..9;  {loop index}
1)	@!match:boolean; {does everything match so far?}
1)	begin match:=true;
1)	for k:=0 to start←vals do
1)	  if start←there[k]and(start←count[k]<>count[k]) then match:=false;
1)	start←match:=match;
1)	end;
1)	@ The |input←ln| routine waits for the user to type a line at his or her
1)	terminal; then it puts ascii-code equivalents for the characters on that line
1)	into the |buffer| array. The |term←in| file is used for terminal input,
1)	and |term←out| for terminal output.
1)	@↑system dependencies@>
1)	@<Glob...@>=
1)	@!buffer:array[0..terminal←line←length] of ascii←code;
1)	@!term←in:text←file; {the terminal, considered as an input file}
1)	@!term←out:text←file; {the terminal, considered as an output file}
1)	@ Since the terminal is being used for both input and output, some systems
**** File 2) DVITYP.WEB[PAS,DEK]/8P/33L
2)	@d errors_only=0 {value of |out_mode| when minimal printing occurs}
2)	@d terse=1 {value of |out_mode| for abbreviated output}
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8

2)	@d verbose=2 {value of |out_mode| for detailed tracing}
2)	@d the_works=3 {|verbose|, plus check of postamble if |random_reading|}
2)	@<Glob...@>=
2)	@!out_mode:errors_only..the_works; {controls the amount of output}
2)	@!max_pages:integer; {at most this many |bop..eop| pages will be printed}
2)	@!resolution:real; {pixels per inch}
2)	@!new_mag:integer; {if positive, overrides the postamble's magnification}
2)	@ The starting page specification is recorded in two arrays called
2)	|start_count| and |start_there|. For example, `\.{1.*.-5}' is represented
2)	by |start_there[0]=true|, |start_count[0]=1|, |start_there[1]=false|,
2)	|start_there[2]=true|, |start_count[2]=-5|.
2)	We also set |start_vals=2|, to indicate that count 2 was the last one
2)	mentioned. The other values of |start_count| and |start_there| are not
2)	important, in this example.
2)	@<Glob...@>=
2)	@!start_count:array[0..9] of integer; {count values to select starting page}
2)	@!start_there:array[0..9] of boolean; {is the |start_count| value relevant?}
2)	@!start_vals:0..9; {the last count considered significant}
2)	@!count:array[0..9] of integer; {the count values on the current page}
2)	@ @<Set init...@>=
2)	out_mode←the_works; max_pages←1000000; start_vals←0; start_there[0]←false;
2)	@ Here is a simple subroutine that tests if the current page might be the
2)	starting page.
2)	@p function start_match:boolean; {does |count| match the starting spec?}
2)	var k:0..9;	{loop index}
2)	@!match:boolean; {does everything match so far?}
2)	begin match←true;
2)	for k←0 to start_vals do
2)		if start_there[k]∧(start_count[k]≠count[k]) then match←false;
2)	start_match←match;
2)	end;
2)	@ The |input_ln| routine waits for the user to type a line at his or her
2)	terminal; then it puts ascii-code equivalents for the characters on that line
2)	into the |buffer| array. The |term_in| file is used for terminal input,
2)	and |term_out| for terminal output.
2)	@↑system dependencies@>
2)	@<Glob...@>=
2)	@!buffer:array[0..terminal_line_length] of ascii_code;
2)	@!term_in:text_file; {the terminal, considered as an input file}
2)	@!term_out:text_file; {the terminal, considered as an output file}
2)	@ Since the terminal is being used for both input and output, some systems
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1293L
1)	subroutine |update←terminal| in order to avoid this problem.
1)	@↑system dependencies@>
1)	@d update←terminal == break(term←out) {empty the terminal output buffer}
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8

1)	@ During the dialog, \.{DVItype} will treat the first blank space in a
1)	line as the end of that line. Therefore |input←ln| makes sure that there
1)	is always at least one blank space in |buffer|.
1)	@↑system dependencies@>
1)	@p procedure input←ln; {inputs a line from the terminal}
1)	var k:0..terminal←line←length;
1)	begin update←terminal; reset(term←in);
1)	if eoln(term←in) then read←ln(term←in);
1)	k:=0;
1)	while (k<terminal←line←length)and not eoln(term←in) do
1)	  begin buffer[k]:=xord[term←in↑]; incr(k); get(term←in);
1)	  end;
1)	buffer[k]:=" ";
1)	end;
1)	@ The global variable |buf←ptr| is used while scanning each line of input;
1)	it points to the first unread character in |buffer|.
1)	@<Glob...@>=
1)	@!buf←ptr:0..terminal←line←length; {the number of characters read}
1)	@ Here is a routine that scans a (possibly signed) integer and computes
1)	the decimal value. If no decimal integer starts at |buf←ptr|, the
1)	value 0 is returned. The integer should be less than $2↑{31}$ in
1)	absolute value.
1)	@p function get←integer:integer;
1)	var x:integer; {accumulates the value}
1)	@!negative:boolean; {should the value be negated?}
1)	begin if buffer[buf←ptr]="-" then
1)	  begin negative:=true; incr(buf←ptr);
1)	  end
1)	else negative:=false;
1)	x:=0;
1)	while (buffer[buf←ptr]>="0")and(buffer[buf←ptr]<="9") do
1)	  begin x:=10*x+buffer[buf←ptr]-"0"; incr(buf←ptr);
1)	  end;
1)	if negative then get←integer:=-x @+ else get←integer:=x;
1)	end;
**** File 2) DVITYP.WEB[PAS,DEK]/8P/89L
2)	subroutine |update_terminal| in order to avoid this problem.
2)	@↑system dependencies@>
2)	@d update_terminal == break(term_out) {empty the terminal output buffer}
2)	@ During the dialog, \.{DVItype} will treat the first blank space in a
2)	line as the end of that line. Therefore |input_ln| makes sure that there
2)	is always at least one blank space in |buffer|.
2)	@↑system dependencies@>
2)	@p procedure input_ln; {inputs a line from the terminal}
2)	var k:0..terminal_line_length;
2)	begin update_terminal; reset(term_in);
2)	if eoln(term_in) then read_ln(term_in);
2)	k←0;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8

2)	while (k<terminal_line_length)∧ not eoln(term_in) do
2)		begin buffer[k]←xord[term_in↑]; incr(k); get(term_in);
2)		end;
2)	buffer[k]←" ";
2)	end;
2)	@ The global variable |buf_ptr| is used while scanning each line of input;
2)	it points to the first unread character in |buffer|.
2)	@<Glob...@>=
2)	@!buf_ptr:0..terminal_line_length; {the number of characters read}
2)	@ Here is a routine that scans a (possibly signed) integer and computes
2)	the decimal value. If no decimal integer starts at |buf_ptr|, the
2)	value 0 is returned. The integer should be less than $2↑{31}$ in
2)	absolute value.
2)	@p function get_integer:integer;
2)	var x:integer; {accumulates the value}
2)	@!negative:boolean; {should the value be negated?}
2)	begin if buffer[buf_ptr]="-" then
2)		begin negative←true; incr(buf_ptr);
2)		end
2)	else negative←false;
2)	x←0;
2)	while (buffer[buf_ptr]≥"0")∧(buffer[buf_ptr]≤"9") do
2)		begin x←10*x+buffer[buf_ptr]-"0"; incr(buf_ptr);
2)		end;
2)	if negative then get_integer←-x @+ else get_integer←x;
2)	end;
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1346L
1)	begin rewrite(term←out); {prepare the terminal for output}
1)	write←ln(term←out,banner);
1)	@<Determine the desired |out←mode|@>;
1)	@<Determine the desired |start←count| values@>;
1)	@<Determine the desired |max←pages|@>;
1)	@<Determine the desired |resolution|@>;
1)	@<Determine the desired |new←mag|@>;
1)	@<Print all the selected options@>;
1)	end;
1)	@ @<Determine the desired |out←mode|@>=
1)	1: write(term←out,'Output level (default=3, ? for help): ');
1)	out←mode:=the←works; input←ln;
1)	if buffer[0]<>" " then
1)	  if (buffer[0]>="0")and(buffer[0]<="3") then out←mode:=buffer[0]-"0"
1)	  else  begin write(term←out,'Type 3 for complete listing,');
1)	    write(term←out,' 0 for errors only,');
1)	    write←ln(term←out,' 1 or 2 for something in between.');
1)	    goto 1;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8

1)	    end
1)	@ @<Determine the desired |start...@>=
1)	2: write(term←out,'Starting page (default=*): ');
1)	start←vals:=0; start←there[0]:=false;
1)	input←ln; buf←ptr:=0; k:=0;
1)	if buffer[0]<>" " then
1)	  repeat if buffer[buf←ptr]="*" then
1)	    begin start←there[k]:=false; incr(buf←ptr);
1)	    end
1)	  else  begin start←there[k]:=true; start←count[k]:=get←integer;
1)	    end;
1)	  if (k<9)and(buffer[buf←ptr]=".") then
1)	    begin incr(k); incr(buf←ptr);
1)	    end
1)	  else if buffer[buf←ptr]=" " then start←vals:=k
1)	  else  begin write(term←out,'Type, e.g., 1.*.-5 to specify the ');
1)	    write←ln(term←out,'first page with \count0=1, \count2=-5.');
1)	    goto 2;
1)	    end;
1)	  until start←vals=k
1)	@ @<Determine the desired |max←pages|@>=
1)	3: write(term←out,'Maximum number of pages (default=1000000): ');
1)	max←pages:=1000000; input←ln; buf←ptr:=0;
1)	if buffer[0]<>" " then
1)	  begin max←pages:=get←integer;
1)	  if max←pages<=0 then
1)	    begin write←ln(term←out,'Please type a positive number.');
1)	    goto 3;
1)	    end;
1)	  end
1)	@ @<Determine the desired |resolution|@>=
1)	4: write(term←out,'Assumed device resolution');
1)	write(term←out,' in pixels per inch (default=240/1): ');
1)	resolution:=240.0; input←ln; buf←ptr:=0;
1)	if buffer[0]<>" " then
1)	  begin k:=get←integer;
1)	  if (k>0)and(buffer[buf←ptr]="/")and
1)	    (buffer[buf←ptr+1]>"0")and(buffer[buf←ptr+1]<="9") then
1)	    begin incr(buf←ptr); resolution:=k/get←integer;
1)	    end
1)	  else  begin write(term←out,'Type a ratio of positive integers;');
1)	    write←ln(term←out,' (1 pixel per mm would be 254/10).');
1)	    goto 4;
1)	    end;
1)	  end
1)	@ @<Determine the desired |new←mag|@>=
1)	5: write(term←out,'New magnification (default=0 to keep the old one): ');
1)	new←mag:=0; input←ln; buf←ptr:=0;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8

1)	if buffer[0]<>" " then
1)	  if (buffer[0]>="0")and(buffer[0]<="9") then new←mag:=get←integer
1)	  else  begin write(term←out,'Type a positive integer to override ');
1)	    write←ln(term←out,'the magnification in the DVI file.');
1)	    goto 5;
1)	    end
1)	@ After the dialog is over, we print the options so that the user
**** File 2) DVITYP.WEB[PAS,DEK]/8P/142L
2)	begin rewrite(term_out); {prepare the terminal for output}
2)	write_ln(term_out,banner);
2)	@<Determine the desired |out_mode|@>;
2)	@<Determine the desired |start_count| values@>;
2)	@<Determine the desired |max_pages|@>;
2)	@<Determine the desired |resolution|@>;
2)	@<Determine the desired |new_mag|@>;
2)	@<Print all the selected options@>;
2)	end;
2)	@ @<Determine the desired |out_mode|@>=
2)	1: write(term_out,'Output level (default=3, ? for help): ');
2)	out_mode←the_works; input_ln;
2)	if buffer[0]≠" " then
2)		if (buffer[0]≥"0")∧(buffer[0]≤"3") then out_mode←buffer[0]-"0"
2)		else	begin write(term_out,'Type 3 for complete listing,');
2)			write(term_out,' 0 for errors only,');
2)			write_ln(term_out,' 1 or 2 for something in between.');
2)			goto 1;
2)			end
2)	@ @<Determine the desired |start...@>=
2)	2: write(term_out,'Starting page (default=*): ');
2)	start_vals←0; start_there[0]←false;
2)	input_ln; buf_ptr←0; k←0;
2)	if buffer[0]≠" " then
2)		repeat if buffer[buf_ptr]="*" then
2)			begin start_there[k]←false; incr(buf_ptr);
2)			end
2)		else	begin start_there[k]←true; start_count[k]←get_integer;
2)			end;
2)		if (k<9)∧(buffer[buf_ptr]=".") then
2)			begin incr(k); incr(buf_ptr);
2)			end
2)		else if buffer[buf_ptr]=" " then start_vals←k
2)		else	begin write(term_out,'Type, e.g., 1.*.-5 to specify the ');
2)			write_ln(term_out,'first page with \count0=1, \count2=-5.');
2)			goto 2;
2)			end;
2)		until start_vals=k
2)	@ @<Determine the desired |max_pages|@>=
2)	3: write(term_out,'Maximum number of pages (default=1000000): ');
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8

2)	max_pages←1000000; input_ln; buf_ptr←0;
2)	if buffer[0]≠" " then
2)		begin max_pages←get_integer;
2)		if max_pages≤0 then
2)			begin write_ln(term_out,'Please type a positive number.');
2)			goto 3;
2)			end;
2)		end
2)	@ @<Determine the desired |resolution|@>=
2)	4: write(term_out,'Assumed device resolution');
2)	write(term_out,' in pixels per inch (default=240/1): ');
2)	resolution←240.0; input_ln; buf_ptr←0;
2)	if buffer[0]≠" " then
2)		begin k←get_integer;
2)		if (k>0)∧(buffer[buf_ptr]="/")∧
2)			(buffer[buf_ptr+1]>"0")∧(buffer[buf_ptr+1]≤"9") then
2)			begin incr(buf_ptr); resolution←k/get_integer;
2)			end
2)		else	begin write(term_out,'Type a ratio of positive integers;');
2)			write_ln(term_out,' (1 pixel per mm would be 254/10).');
2)			goto 4;
2)			end;
2)		end
2)	@ @<Determine the desired |new_mag|@>=
2)	5: write(term_out,'New magnification (default=0 to keep the old one): ');
2)	new_mag←0; input_ln; buf_ptr←0;
2)	if buffer[0]≠" " then
2)		if (buffer[0]≥"0")∧(buffer[0]≤"9") then new_mag←get_integer
2)		else	begin write(term_out,'Type a positive integer to override ');
2)			write_ln(term_out,'the magnification in the DVI file.');
2)			goto 5;
2)			end
2)	@ After the dialog is over, we print the options so that the user
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1428L
1)	print←ln('Options selected:');
1)	@.Options selected@>
1)	print('  Starting page = ');
1)	for k:=0 to start←vals do
1)	  begin if start←there[k] then print(start←count[k]:0)
1)	  else print('*');
1)	  if k<start←vals then print('.')
1)	  else print←ln(' ');
1)	  end;
1)	print←ln('  Maximum number of pages = ',max←pages:0);
1)	print('  Output level = ',out←mode:0);
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8

1)	case out←mode of
1)	errors←only: print←ln(' (showing bops, fonts, and error messages only)');
1)	terse: print←ln(' (terse)');
1)	verbose: print←ln(' (verbose)');
1)	the←works: if random←reading then print←ln(' (the works)')
1)	  else  begin out←mode:=verbose;
1)	    print←ln(' (the works: same as level 2 in this DVItype)');
1)	    end;
1)	end;@/
1)	print←ln('  Resolution = ',resolution:12:8,' pixels per inch');
1)	if new←mag>0 then print←ln('  New magnification factor = ',new←mag/1000:8:3)
1)	@* Defining fonts.
1)	When |out←mode=the←works|, \.{DVItype} reads the postamble first and loads
1)	all of the donts defined there; then it processed the pages. In this
1)	case, a \\{fnt\←def} command should match a previous definition if and only
1)	if the \\{fnt\←def} being processed is not in the postamble. But if
1)	|out←mode<the←works|, \.{DVItype} reads the pages first and the postamble
1)	last, so the conventions are reversed: a \\{fnt\←def} should match a previous
1)	\\{fnt\←def} if and only if the current one is a part of the postamble.
1)	A global variable |in←postamble| is provided to tell whether we are
1)	processing the postamble or not.
1)	@<Glob...@>=
1)	@!in←postamble:boolean; {are we reading the postamble?}
1)	@ @<Set init...@>=
1)	in←postamble:=false;
1)	@ The following subroutine does the necessary things when a \\{fnt\←def}
1)	command is being processed.
1)	@p procedure define←font(@!e:integer); {|e| is an external font number}
1)	var f:0..max←fonts;
1)	@!p:integer; {length of the area/directory spec}
**** File 2) DVITYP.WEB[PAS,DEK]/8P/224L
2)	print_ln('Options selected:');
2)	@.Options selected@>
2)	print('  Starting page = ');
2)	for k←0 to start_vals do
2)		begin if start_there[k] then print(start_count[k]:0)
2)		else print('*');
2)		if k<start_vals then print('.')
2)		else print_ln(' ');
2)		end;
2)	print_ln('  Maximum number of pages = ',max_pages:0);
2)	print('  Output level = ',out_mode:0);
2)	case out_mode of
2)	errors_only: print_ln(' (showing bops, fonts, and error messages only)');
2)	terse: print_ln(' (terse)');
2)	verbose: print_ln(' (verbose)');
2)	the_works: if random_reading then print_ln(' (the works)')
2)		else	begin out_mode←verbose;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,8

2)			print_ln(' (the works: same as level 2 in this DVItype)');
2)			end;
2)	end;@/
2)	print_ln('  Resolution = ',resolution:12:8,' pixels per inch');
2)	if new_mag>0 then print_ln('  New magnification factor = ',new_mag/1000:8:3)
2)	@* Defining fonts.
2)	When |out_mode=the_works|, \.{DVItype} reads the postamble first and loads
2)	all of the donts defined there; then it processes the pages. In this
2)	case, a \\{fnt\_def} command should match a previous definition if and only
2)	if the \\{fnt\_def} being processed is not in the postamble. But if
2)	|out_mode<the_works|, \.{DVItype} reads the pages first and the postamble
2)	last, so the conventions are reversed: a \\{fnt\_def} should match a previous
2)	\\{fnt\_def} if and only if the current one is a part of the postamble.
2)	A global variable |in_postamble| is provided to tell whether we are
2)	processing the postamble or not.
2)	@<Glob...@>=
2)	@!in_postamble:boolean; {are we reading the postamble?}
2)	@ @<Set init...@>=
2)	in_postamble←false;
2)	@ The following subroutine does the necessary things when a \\{fnt\_def}
2)	command is being processed.
2)	@p procedure define_font(@!e:integer); {|e| is an external font number}
2)	var f:0..max_fonts;
2)	@!p:integer; {length of the area/directory spec}
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1477L
1)	@!r:0..name←length; {index into |cur←name|}
1)	@!j,@!k:0..name←size; {indices into |names|}
1)	@!mismatch:boolean; {do names disagree?}
1)	begin if nf=max←fonts then abort('DVItype capacity exceeded (max fonts=',
1)	    max←fonts:0,')!');
1)	@.DVItype capacity exceeded...@>
1)	font←num[nf]:=e; f:=0;
1)	while font←num[f]<>e do incr(f);
1)	@<Read the font parameters into position for font |nf|, and
1)	  print the font name@>;
1)	if ((out←mode=the←works)and in←postamble)or@|
1)	   ((out←mode<the←works)and not in←postamble) then
1)	  begin if f<nf then print←ln('---this font was already defined!');
1)	@.this font was already defined@>
1)	  end
1)	else  begin if f=nf then print←ln('---this font wasn''t loaded before!');
1)	@.this font wasn't loaded before@>
1)	  end;
1)	if f=nf then @<Load the new font, unless there are problems@>
**** File 2) DVITYP.WEB[PAS,DEK]/9P/27L
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,9

2)	@!r:0..name_length; {index into |cur_name|}
2)	@!j,@!k:0..name_size; {indices into |names|}
2)	@!mismatch:boolean; {do names disagree?}
2)	begin if nf=max_fonts then abort('DVItype capacity exceeded (max fonts=',
2)			max_fonts:0,')!');
2)	@.DVItype capacity exceeded...@>
2)	font_num[nf]←e; f←0;
2)	while font_num[f]≠e do incr(f);
2)	@<Read the font parameters into position for font |nf|, and
2)		print the font name@>;
2)	if ((out_mode=the_works)∧ in_postamble)∨@|
2)		 ((out_mode<the_works)∧ ¬ in_postamble) then
2)		begin if f<nf then print_ln('---this font was already defined!');
2)	@.this font was already defined@>
2)		end
2)	else	begin if f=nf then print_ln('---this font wasn''t loaded before!');
2)	@.this font wasn't loaded before@>
2)		end;
2)	if f=nf then @<Load the new font, unless there are problems@>
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1500L
1)	begin if font←check←sum[f]<>c then
1)	  print←ln('---check sum doesn''t match previous definition!');
1)	@.check sum doesn't match@>
1)	if font←scaled←size[f]<>q then
1)	  print←ln('---scaled size doesn''t match previous definition!');
1)	@.scaled size doesn't match@>
1)	if font←design←size[f]<>d then
1)	  print←ln('---design size doesn''t match previous definition!');
1)	@.design size doesn't match@>
1)	j:=font←name[f]; k:=font←name[nf]; mismatch:=false;
1)	while j<font←name[f+1] do
1)	  begin if names[j]<>names[k] then mismatch:=true;
1)	  incr(j); incr(k);
1)	  end;
1)	if k<>font←name[nf+1] then mismatch:=true;
1)	if mismatch then print←ln('---font name doesn''t match previous definition!');
1)	@.font name doesn't match@>
**** File 2) DVITYP.WEB[PAS,DEK]/9P/50L
2)	begin if font_check_sum[f]≠c then
2)		print_ln('---check sum doesn''t match previous definition!');
2)	@.check sum doesn't match@>
2)	if font_scaled_size[f]≠q then
2)		print_ln('---scaled size doesn''t match previous definition!');
2)	@.scaled size doesn't match@>
2)	if font_design_size[f]≠d then
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,9

2)		print_ln('---design size doesn''t match previous definition!');
2)	@.design size doesn't match@>
2)	j←font_name[f]; k←font_name[nf]; mismatch←false;
2)	while j<font_name[f+1] do
2)		begin if names[j]≠names[k] then mismatch←true;
2)		incr(j); incr(k);
2)		end;
2)	if k≠font_name[nf+1] then mismatch←true;
2)	if mismatch then print_ln('---font name doesn''t match previous definition!');
2)	@.font name doesn't match@>
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1520L
1)	c:=signed←quad; font←check←sum[nf]:=c;@/
1)	q:=signed←quad; font←scaled←size[nf]:=q;@/
1)	d:=signed←quad; font←design←size[nf]:=d;@/
1)	p:=get←byte; n:=get←byte;
1)	if font←name[nf]+n+p>name←size then
1)	  abort('DVItype capacity exceeded (name size=',name←size:0,')!');
1)	@.DVItype capacity exceeded...@>
1)	font←name[nf+1]:=font←name[nf]+n+p;
1)	if showing then print(': ')
1)	  {when |showing| is true, the font number has already been printed}
1)	else print('Font ',e:0,': ');
**** File 2) DVITYP.WEB[PAS,DEK]/9P/70L
2)	c←signed_quad; font_check_sum[nf]←c;@/
2)	q←signed_quad; font_scaled_size[nf]←q;@/
2)	d←signed_quad; font_design_size[nf]←d;@/
2)	p←get_byte; n←get_byte;
2)	if font_name[nf]+n+p>name_size then
2)		abort('DVItype capacity exceeded (name size=',name_size:0,')!');
2)	@.DVItype capacity exceeded...@>
2)	font_name[nf+1]←font_name[nf]+n+p;
2)	if showing then print(': ')
2)		{when |showing| is true, the font number has already been printed}
2)	else print('Font ',e:0,': ');
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1533L
1)	else for k:=font←name[nf] to font←name[nf+1]-1 do names[k]:=get←byte;
1)	incr(nf); print←font(nf-1); decr(nf)
1)	@ @<Load the new font, unless there are problems@>=
1)	begin @<Move font name into the |cur←name| string@>;
1)	open←tfm←file;
1)	if eof(tfm←file) then
1)	  print('---not loaded, TFM file can''t be opened!')
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,9

1)	@.TFM file can\'t be opened@>
1)	else  begin if (q<=0)or(q>=@'1000000000) then
1)	    print('---not loaded, bad scale (',q:0,')!')
1)	@.bad scale@>
1)	  else if (d<=0)or(d>=@'1000000000) then
1)	    print('---not loaded, bad design size (',d:0,')!')
1)	@.bad design size@>
1)	  else if in←TFM(q) then @<Finish loading the new font info@>;
1)	  end;
1)	if out←mode=errors←only then print←ln(' ');
1)	end
1)	@ @<Finish loading...@>=
1)	begin font←space[nf]:=q div 6; {this is a 3-unit ``thin space''}
1)	if (c<>0)and(tfm←check←sum<>0)and(c<>tfm←check←sum) then
1)	  begin print←ln('---beware: check sums do not agree!');
1)	@.beware: check sums do not agree@>
1)	@.check sums do not agree@>
1)	  print←ln('   (',c:0,' vs. ',tfm←check←sum:0,')');
1)	  print('   ');
1)	  end;
1)	print('---loaded at size ',q:0,' DVI units');
1)	d:=trunc((100.0*conv*q)/(true←conv*d)+0.5);
1)	if d<>100 then
1)	  begin print←ln(' '); print(' (this font is magnified ',d:0,'%)');
1)	  end;
1)	@.this font is magnified@>
**** File 2) DVITYP.WEB[PAS,DEK]/9P/83L
2)	else for k←font_name[nf] to font_name[nf+1]-1 do names[k]←get_byte;
2)	incr(nf); print_font(nf-1); decr(nf)
2)	@ @<Load the new font, unless there are problems@>=
2)	begin @<Move font name into the |cur_name| string@>;
2)	open_tfm_file;
2)	if eof(tfm_file) then
2)		print('---not loaded, TFM file can''t be opened!')
2)	@.TFM file can\'t be opened@>
2)	else	begin if (q≤0)∨(q≥@'1000000000) then
2)			print('---not loaded, bad scale (',q:0,')!')
2)	@.bad scale@>
2)		else if (d≤0)∨(d≥@'1000000000) then
2)			print('---not loaded, bad design size (',d:0,')!')
2)	@.bad design size@>
2)		else if in_TFM(q) then @<Finish loading the new font info@>;
2)		end;
2)	if out_mode=errors_only then print_ln(' ');
2)	end
2)	@ @<Finish loading...@>=
2)	begin font_space[nf]←q div 6; {this is a 3-unit ``thin space''}
2)	if (c≠0)∧(tfm_check_sum≠0)∧(c≠tfm_check_sum) then
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,9

2)		begin print_ln('---beware: check sums do not agree!');
2)	@.beware: check sums do not agree@>
2)	@.check sums do not agree@>
2)		print_ln('   (',c:0,' vs. ',tfm_check_sum:0,')');
2)		print('   ');
2)		end;
2)	print('---loaded at size ',q:0,' DVI units');
2)	d←trunc((100.0*conv*q)/(true_conv*d)+0.5);
2)	if d≠100 then
2)		begin print_ln(' '); print(' (this font is magnified ',d:0,'%)');
2)		end;
2)	@.this font is magnified@>
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1574L
1)	The string variable |default←directory| contains the name of this area.
1)	@↑system dependencies@>
1)	@d default←directory←name=='<SYS.FONTS>' {change this to the correct name}
1)	@d default←directory←name←length=11 {change this to the correct length}
1)	@<Glob...@>=
1)	@!default←directory:packed array[1..default←directory←name←length] of char;
1)	@ @<Set init...@>=
1)	default←directory:=default←directory←name;
1)	@ The string |cur←name| is supposed to be set to the external name of the
1)	\.{TFM} file for the current font. This usually means that we need to
**** File 2) DVITYP.WEB[PAS,DEK]/9P/124L
2)	The string variable |default_directory| contains the name of this area.
2)	@↑system dependencies@>
2)	@d default_directory_name=='<SYS.FONTS>' {change this to the correct name}
2)	@d default_directory_name_length=11 {change this to the correct length}
2)	@<Glob...@>=
2)	@!default_directory:packed array[1..default_directory_name_length] of char;
2)	@ @<Set init...@>=
2)	default_directory←default_directory_name;
2)	@ The string |cur_name| is supposed to be set to the external name of the
2)	\.{TFM} file for the current font. This usually means that we need to
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1590L
1)	to upper case, since |cur←name| is a \PASCAL\ string.
1)	@↑system dependencies@>
1)	@<Move font name into the |cur←name| string@>=
1)	for k:=1 to name←length do cur←name[k]:=' ';
1)	if p=0 then
1)	  begin for k:=1 to default←directory←name←length do
1)	    cur←name[k]:=default←directory[k];
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,9

1)	  r:=default←directory←name←length;
1)	  end
1)	else r:=0;
1)	for k:=font←name[nf] to font←name[nf+1]-1 do
1)	  begin incr(r);
1)	  if r+4>name←length then
1)	    abort('DVItype capacity exceeded (max font name length=',
1)	      name←length:0,')!');
1)	@.DVItype capacity exceeded...@>
1)	  if (names[k]>="a")and(names[k]<="z") then
1)	      cur←name[r]:=xchr[names[k]-@'40]
1)	  else cur←name[r]:=xchr[names[k]];
1)	  end;
1)	cur←name[r+1]:='.'; cur←name[r+2]:='T'; cur←name[r+3]:='F'; cur←name[r+4]:='M'
1)	@* Low level output routines.
1)	Simple text in the \.{DVI} file is saved in a buffer until |line←length-2|
1)	characters have accumulated, or until some non-simple \.{DVI} operation
1)	occurs. Then the accumulated text is printed on a line, surrounded by
1)	brackets. The global variable |text←ptr| keeps track of the number of
1)	characters currently in the buffer.
1)	@<Glob...@>=
1)	@!text←ptr:0..line←length; {the number of characters in |text←buf|}
1)	@!text←buf:array[1..line←length] of ascii←code; {saved characters}
1)	@ @<Set init...@>=
1)	text←ptr:=0;
1)	@ The |flush←text| procedure will empty the buffer if there is something in it.
1)	@p procedure flush←text;
1)	var k:0..line←length; {index into |text←buf|}
1)	begin if text←ptr>0 then
1)	  begin if out←mode>errors←only then
1)	    begin print('[');
1)	    for k:=1 to text←ptr do print(xchr[text←buf[k]]);
1)	    print←ln(']');
1)	    end;
1)	  text←ptr:=0;
1)	  end;
1)	end;
1)	@ And the |out←text| procedure puts something in it.
1)	@p procedure out←text(c:ascii←code);
1)	begin if text←ptr=line←length-2 then flush←text;
1)	incr(text←ptr); text←buf[text←ptr]:=c;
1)	end;
1)	@* Translation to symbolic form.
1)	The main work of \.{DVItype} is accomplished by the |do←page| procedure,
1)	which produces the output for an entire page, assuming that the |bop|
**** File 2) DVITYP.WEB[PAS,DEK]/9P/140L
2)	to upper case, since |cur_name| is a \PASCAL\ string.
2)	@↑system dependencies@>
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,9

2)	@<Move font name into the |cur_name| string@>=
2)	for k←1 to name_length do cur_name[k]←' ';
2)	if p=0 then
2)		begin for k←1 to default_directory_name_length do
2)			cur_name[k]←default_directory[k];
2)		r←default_directory_name_length;
2)		end
2)	else r←0;
2)	for k←font_name[nf] to font_name[nf+1]-1 do
2)		begin incr(r);
2)		if r+4>name_length then
2)			abort('DVItype capacity exceeded (max font name length=',
2)				name_length:0,')!');
2)	@.DVItype capacity exceeded...@>
2)		if (names[k]≥"a")∧(names[k]≤"z") then
2)				cur_name[r]←xchr[names[k]-@'40]
2)		else cur_name[r]←xchr[names[k]];
2)		end;
2)	cur_name[r+1]←'.'; cur_name[r+2]←'T'; cur_name[r+3]←'F'; cur_name[r+4]←'M'
2)	@* Low level output routines.
2)	Simple text in the \.{DVI} file is saved in a buffer until |line_length-2|
2)	characters have accumulated, or until some non-simple \.{DVI} operation
2)	occurs. Then the accumulated text is printed on a line, surrounded by
2)	brackets. The global variable |text_ptr| keeps track of the number of
2)	characters currently in the buffer.
2)	@<Glob...@>=
2)	@!text_ptr:0..line_length; {the number of characters in |text_buf|}
2)	@!text_buf:array[1..line_length] of ascii_code; {saved characters}
2)	@ @<Set init...@>=
2)	text_ptr←0;
2)	@ The |flush_text| procedure will empty the buffer if there is something in it.
2)	@p procedure flush_text;
2)	var k:0..line_length; {index into |text_buf|}
2)	begin if text_ptr>0 then
2)		begin if out_mode>errors_only then
2)			begin print('[');
2)			for k←1 to text_ptr do print(xchr[text_buf[k]]);
2)			print_ln(']');
2)			end;
2)		text_ptr←0;
2)		end;
2)	end;
2)	@ And the |out_text| procedure puts something in it.
2)	@p procedure out_text(c:ascii_code);
2)	begin if text_ptr=line_length-2 then flush_text;
2)	incr(text_ptr); text_buf[text_ptr]←c;
2)	end;
2)	@* Translation to symbolic form.
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,9

2)	The main work of \.{DVItype} is accomplished by the |do_page| procedure,
2)	which produces the output for an entire page, assuming that the |bop|
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1658L
1)	since it is not always true that |hh=pixel←round(h)| or
1)	|vv=pixel←round(v)|.
1)	The stack of $(h,v,w,x,y,z)$ values is represented by eight arrays
**** File 2) DVITYP.WEB[PAS,DEK]/11P/11L
2)	since it is not always true that |hh=pixel_round(h)| or
2)	|vv=pixel_round(v)|.
2)	The stack of $(h,v,w,x,y,z)$ values is represented by eight arrays
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1667L
1)	  array [0..stack←size] of integer; {pushed down values in \.{DVI} units}
1)	@!hhstack,@!vvstack:
1)	  array [0..stack←size] of integer; {pushed down values in pixels}
1)	@ Three characteristics of the pages (their |max←v|, |max←h|, and
1)	|max←s|) are specified in the postamble, and a warning message
1)	is printed if these limits are exceeded. Actually |max←v| is set to
1)	the maximum height plus depth of a page, and |max←h| to the maximum width,
1)	for purposes of page layout. Since characters can legally be set outside
1)	of the page boundaries, it is not an error when |max←v| or |max←h| is
1)	exceeded. But |max←s| should not be exceeded.
1)	The postamble also specifies the total number of pages; \.{DVItype}
**** File 2) DVITYP.WEB[PAS,DEK]/11P/20L
2)		array [0..stack_size] of integer; {pushed down values in \.{DVI} units}
2)	@!hhstack,@!vvstack:
2)		array [0..stack_size] of integer; {pushed down values in pixels}
2)	@ Three characteristics of the pages (their |max_v|, |max_h|, and
2)	|max_s|) are specified in the postamble, and a warning message
2)	is printed if these limits are exceeded. Actually |max_v| is set to
2)	the maximum height plus depth of a page, and |max_h| to the maximum width,
2)	for purposes of page layout. Since characters can legally be set outside
2)	of the page boundaries, it is not an error when |max_v| or |max_h| is
2)	exceeded. But |max_s| should not be exceeded.
2)	The postamble also specifies the total number of pages; \.{DVItype}
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1683L
1)	@!max←v:integer; {the value of |abs(v)| should probably not exceed this}
1)	@!max←h:integer; {the value of |abs(h)| should probably not exceed this}
1)	@!max←s:integer; {the stack depth should not exceed this}
1)	@!max←v←so←far,@!max←h←so←far,@!max←s←so←far:integer; {the record high levels}
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11

1)	@!total←pages:integer; {the stated total number of pages}
1)	@!page←count:integer; {the total number of pages seen so far}
1)	@ @<Set init...@>=
1)	max←v:=@'17777777777; max←h:=@'17777777777; max←s:=stack←size+1;@/
1)	max←v←so←far:=0; max←h←so←far:=0; max←s←so←far:=0; page←count:=0;
1)	@ Before we get into the details of |do←page|, it is convenient to
1)	consider a simpler routine that computes the first parameter of each
1)	opcode.
1)	@d four←cases(#)==#,#+1,#+2,#+3
1)	@d eight←cases(#)==four←cases(#),four←cases(#+4)
1)	@d sixteen←cases(#)==eight←cases(#),eight←cases(#+8)
1)	@d thirty←two←cases(#)==sixteen←cases(#),sixteen←cases(#+16)
1)	@d sixty←four←cases(#)==thirty←two←cases(#),thirty←two←cases(#+32)
1)	@p function first←par(o:eight←bits):integer;
1)	begin case o of
1)	sixty←four←cases(set←char←0),sixty←four←cases(set←char←0+64):
1)	  first←par:=o-set←char←0;
1)	set1,put1,fnt1,xxx1,fnt←def1: first←par:=get←byte;
1)	set1+1,put1+1,fnt1+1,xxx1+1,fnt←def1+1: first←par:=get←two←bytes;
1)	set1+2,put1+2,fnt1+2,xxx1+2,fnt←def1+2: first←par:=get←three←bytes;
1)	right1,w1,x1,down1,y1,z1: first←par:=signed←byte;
1)	right1+1,w1+1,x1+1,down1+1,y1+1,z1+1: first←par:=signed←pair;
1)	right1+2,w1+2,x1+2,down1+2,y1+2,z1+2: first←par:=signed←trio;
1)	set1+3,set←rule,put1+3,put←rule,right1+3,w1+3,x1+3,down1+3,y1+3,z1+3,
1)	  fnt1+3,xxx1+3,fnt←def1+3: first←par:=signed←quad;
1)	nop,bop,eop,push,pop,pre,post,post←post,undefined←commands: first←par:=0;
1)	w0: first←par:=w;
1)	x0: first←par:=x;
1)	y0: first←par:=y;
1)	z0: first←par:=z;
1)	sixty←four←cases(fnt←num←0): first←par:=o-fnt←num←0;
1)	end;
**** File 2) DVITYP.WEB[PAS,DEK]/11P/36L
2)	@!max_v:integer; {the value of |abs(v)| should probably not exceed this}
2)	@!max_h:integer; {the value of |abs(h)| should probably not exceed this}
2)	@!max_s:integer; {the stack depth should not exceed this}
2)	@!max_v_so_far,@!max_h_so_far,@!max_s_so_far:integer; {the record high levels}
2)	@!total_pages:integer; {the stated total number of pages}
2)	@!page_count:integer; {the total number of pages seen so far}
2)	@ @<Set init...@>=
2)	max_v←@'17777777777; max_h←@'17777777777; max_s←stack_size+1;@/
2)	max_v_so_far←0; max_h_so_far←0; max_s_so_far←0; page_count←0;
2)	@ Before we get into the details of |do_page|, it is convenient to
2)	consider a simpler routine that computes the first parameter of each
2)	opcode.
2)	@d four_cases(#)==#,#+1,#+2,#+3
2)	@d eight_cases(#)==four_cases(#),four_cases(#+4)
2)	@d sixteen_cases(#)==eight_cases(#),eight_cases(#+8)
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11

2)	@d thirty_two_cases(#)==sixteen_cases(#),sixteen_cases(#+16)
2)	@d sixty_four_cases(#)==thirty_two_cases(#),thirty_two_cases(#+32)
2)	@p function first_par(o:eight_bits):integer;
2)	begin case o of
2)	sixty_four_cases(set_char_0),sixty_four_cases(set_char_0+64):
2)		first_par←o-set_char_0;
2)	set1,put1,fnt1,xxx1,fnt_def1: first_par←get_byte;
2)	set1+1,put1+1,fnt1+1,xxx1+1,fnt_def1+1: first_par←get_two_bytes;
2)	set1+2,put1+2,fnt1+2,xxx1+2,fnt_def1+2: first_par←get_three_bytes;
2)	right1,w1,x1,down1,y1,z1: first_par←signed_byte;
2)	right1+1,w1+1,x1+1,down1+1,y1+1,z1+1: first_par←signed_pair;
2)	right1+2,w1+2,x1+2,down1+2,y1+2,z1+2: first_par←signed_trio;
2)	set1+3,set_rule,put1+3,put_rule,right1+3,w1+3,x1+3,down1+3,y1+3,z1+3,
2)		fnt1+3,xxx1+3,fnt_def1+3: first_par←signed_quad;
2)	nop,bop,eop,push,pop,pre,post,post_post,undefined_commands: first_par←0;
2)	w0: first_par←w;
2)	x0: first_par←x;
2)	y0: first_par←y;
2)	z0: first_par←z;
2)	sixty_four_cases(fnt_num_0): first_par←o-fnt_num_0;
2)	end;
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1735L
1)	@p function rule←pixels(x:integer):integer;
1)	  {computes $\lceil|conv|\cdot x\rceil$}
1)	var n:integer;
1)	begin n:=trunc(conv*x);
1)	if n<conv*x then rule←pixels:=n+1 @+ else rule←pixels:=n;
1)	end;
1)	@ Strictly speaking, the |do←page| procedure is really a function with
1)	side effects, not a `\&{procedure}'; it returns the value |false| if
**** File 2) DVITYP.WEB[PAS,DEK]/11P/88L
2)	@p function rule_pixels(x:integer):integer;
2)		{computes $\lceil|conv|\cdot x\rceil$}
2)	var n:integer;
2)	begin n←trunc(conv*x);
2)	if n<conv*x then rule_pixels←n+1 @+ else rule_pixels←n;
2)	end;
2)	@ Strictly speaking, the |do_page| procedure is really a function with
2)	side effects, not a `\&{procedure}'; it returns the value |false| if
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1750L
1)	@d fin←set=41 {label for commands that set or put a character}
1)	@d fin←rule=42 {label for commands that set or put a rule}
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11

1)	@d move←right=43 {label for commands that change |h|}
1)	@d move←down=44 {label for commands that change |v|}
1)	@d show←state=45 {label for commands that change |s|}
1)	@d change←font=46 {label for commands that change |cur←font|}
1)	@ Some \PASCAL\ compilers severely restrict the length of procedure bodies,
1)	so we shall split |do←page| into two parts, one of which is
1)	called |special←cases|. The different parts communicate with each other
1)	via the global variables mentioned above, together with the following ones:
**** File 2) DVITYP.WEB[PAS,DEK]/11P/103L
2)	@d fin_set=41 {label for commands that set or put a character}
2)	@d fin_rule=42 {label for commands that set or put a rule}
2)	@d move_right=43 {label for commands that change |h|}
2)	@d move_down=44 {label for commands that change |v|}
2)	@d show_state=45 {label for commands that change |s|}
2)	@d change_font=46 {label for commands that change |cur_font|}
2)	@ Some \PASCAL\ compilers severely restrict the length of procedure bodies,
2)	so we shall split |do_page| into two parts, one of which is
2)	called |special_cases|. The different parts communicate with each other
2)	via the global variables mentioned above, together with the following ones:
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1765L
1)	@!cur←font:integer; {current internal font number}
1)	@!showing:boolean; {is the current command being translated in full?}
1)	@ Here is the overall setup.
1)	@p @<Declare the function called |special←cases|@>@;
1)	function do←page:boolean;
1)	label fin←set,fin←rule,move←right,show←state,done,9998,9999;
1)	var o:eight←bits; {operation code of the current command}
1)	@!p,@!q:integer; {parameters of the current command}
1)	@!a:integer; {byte number of the current command}
1)	begin cur←font:=nf; {set current font undefined}
1)	s:=0; h:=0; v:=0; w:=0; x:=0; y:=0; z:=0; hh:=0; vv:=0;
1)	  {initialize the state variables}
1)	while true do @<Translate the next command in the \.{DVI} file;
1)	    |goto 9999| with |do←page=true| if it was |eop|;
1)	    |goto 9998| if premature termination is needed@>;
1)	9998: print←ln('!'); do←page:=false;
1)	9999: end;
**** File 2) DVITYP.WEB[PAS,DEK]/11P/118L
2)	@!cur_font:integer; {current internal font number}
2)	@!showing:boolean; {is the current command being translated in full?}
2)	@ Here is the overall setup.
2)	@p @<Declare the function called |special_cases|@>@;
2)	function do_page:boolean;
2)	label fin_set,fin_rule,move_right,show_state,done,9998,9999;
2)	var o:eight_bits; {operation code of the current command}
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11

2)	@!p,@!q:integer; {parameters of the current command}
2)	@!a:integer; {byte number of the current command}
2)	begin cur_font←nf; {set current font undefined}
2)	s←0; h←0; v←0; w←0; x←0; y←0; z←0; hh←0; vv←0;
2)		{initialize the state variables}
2)	while true do @<Translate the next command in the \.{DVI} file;
2)			|goto 9999| with |do_page=true| if it was |eop|;
2)			|goto 9998| if premature termination is needed@>;
2)	9998: print_ln('!'); do_page←false;
2)	9999: end;
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1790L
1)	only if |out←mode>=verbose|.
1)	@d show(#)==begin flush←text; showing:=true; print(a:0,': ',#);
1)	  end
1)	@d major(#)==if out←mode>errors←only then show(#)
1)	@d minor(#)==if out←mode>=verbose then
1)	  begin showing:=true; print(a:0,': ',#);
1)	  end
1)	@d error(#)==if not showing then show(#) else print(' ',#)
1)	@<Translate the next command...@>=
1)	begin a:=cur←loc; showing:=false;
1)	o:=get←byte; p:=first←par(o);
1)	if eof(dvi←file) then abort('the file ended prematurely!');
1)	@.the file ended prematurely@>
1)	@<Start translation of command |o| and |goto| the appropriate label to
1)	  finish the job@>;
1)	fin←set: @<Finish a command that either sets or puts a character, then
1)	    |goto move←right| or |done|@>;
1)	fin←rule: @<Finish a command that either sets or puts a rule, then
1)	    |goto move←right| or |done|@>;
1)	move←right: @<Finish a command that sets |h:=h+q|, then |goto done|@>;
1)	show←state: @<Show the values of |ss|, |h|, |v|, |w|, |x|, |y|, |z|,
1)	  |hh|, and |vv|; then |goto done|@>;
1)	done: if showing then print←ln(' ');
1)	end
1)	@ The multiway switch in |first←par|, above, was organized by the length
1)	of each command; the one in |do←page| is organized by the semantics.
1)	@<Start translation...@>=
1)	if o<set←char←0+128 then @<Translate a |set←char| command@>
1)	else case o of
1)	  four←cases(set1): begin major('set',o-set1+1:0,' ',p:0); goto fin←set;
1)	    end;
1)	  set←rule: begin major('setrule'); goto fin←rule;
1)	    end;
1)	  put←rule: begin major('putrule'); goto fin←rule;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11

1)	    end;
1)	  @t\4@>@<Cases for commands |nop|, |bop|, $\ldotss$, |pop|@>@;
1)	  @t\4@>@<Cases for horizontal motion@>@;
1)	  othercases if special←cases(o,p,a) then goto done@+else goto 9998
1)	  endcases
1)	@ @<Declare the function called |special←cases|@>=
1)	function special←cases(@!o:eight←bits;@!p,@!a:integer):boolean;
1)	label change←font,move←down,done,9998;
1)	var q:integer; {parameter of the current command}
1)	@!k:integer; {loop index}
1)	@!bad←char:boolean; {has a non-ascii character code appeared in this |xxx|?}
1)	@!pure:boolean; {is the command error-free?}
1)	begin pure:=true;
1)	case o of
1)	four←cases(put1): begin major('put',o-put1+1:0,' ',p:0); goto done;
1)	  end;
1)	@t\4@>@<Cases for vertical motion@>@;
1)	@t\4@>@<Cases for fonts@>@;
1)	four←cases(xxx1): @<Translate an |xxx| command and |goto done|@>;
1)	pre: begin error('preamble command within a page!'); goto 9998;
1)	  end;
1)	@.preamble command within a page@>
1)	post,post←post: begin error('postamble command within a page!'); goto 9998;
1)	@.postamble command within a page@>
1)	  end;
1)	othercases begin error('undefined command ',o:0,'!');
1)	  goto done;
1)	@.undefined command@>
1)	  end
1)	endcases;
1)	move←down: @<Finish a command that sets |v:=v+p|, then |goto done|@>;
1)	change←font: @<Finish a command that changes the current font,
1)	  then |goto done|@>;
1)	9998: pure:=false;
1)	done: special←cases:=pure;
1)	end;
**** File 2) DVITYP.WEB[PAS,DEK]/11P/143L
2)	only if |out_mode≥verbose|.
2)	@d show(#)==begin flush_text; showing←true; print(a:0,': ',#);
2)		end
2)	@d major(#)==if out_mode>errors_only then show(#)
2)	@d minor(#)==if out_mode≥verbose then
2)		begin showing←true; print(a:0,': ',#);
2)		end
2)	@d error(#)==if not showing then show(#) else print(' ',#)
2)	@<Translate the next command...@>=
2)	begin a←cur_loc; showing←false;
2)	o←get_byte; p←first_par(o);
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11

2)	if eof(dvi_file) then abort('the file ended prematurely!');
2)	@.the file ended prematurely@>
2)	@<Start translation of command |o| and |goto| the appropriate label to
2)		finish the job@>;
2)	fin_set: @<Finish a command that either sets or puts a character, then
2)			|goto move_right| or |done|@>;
2)	fin_rule: @<Finish a command that either sets or puts a rule, then
2)			|goto move_right| or |done|@>;
2)	move_right: @<Finish a command that sets |h←h+q|, then |goto done|@>;
2)	show_state: @<Show the values of |ss|, |h|, |v|, |w|, |x|, |y|, |z|,
2)		|hh|, and |vv|; then |goto done|@>;
2)	done: if showing then print_ln(' ');
2)	end
2)	@ The multiway switch in |first_par|, above, was organized by the length
2)	of each command; the one in |do_page| is organized by the semantics.
2)	@<Start translation...@>=
2)	if o<set_char_0+128 then @<Translate a |set_char| command@>
2)	else case o of
2)		four_cases(set1): begin major('set',o-set1+1:0,' ',p:0); goto fin_set;
2)			end;
2)		set_rule: begin major('setrule'); goto fin_rule;
2)			end;
2)		put_rule: begin major('putrule'); goto fin_rule;
2)			end;
2)		@t\4@>@<Cases for commands |nop|, |bop|, $\ldotss$, |pop|@>@;
2)		@t\4@>@<Cases for horizontal motion@>@;
2)		othercases if special_cases(o,p,a) then goto done@+else goto 9998
2)		endcases
2)	@ @<Declare the function called |special_cases|@>=
2)	function special_cases(@!o:eight_bits;@!p,@!a:integer):boolean;
2)	label change_font,move_down,done,9998;
2)	var q:integer; {parameter of the current command}
2)	@!k:integer; {loop index}
2)	@!bad_char:boolean; {has a non-ascii character code appeared in this \\{xxx}?}
2)	@!pure:boolean; {is the command error-free?}
2)	begin pure←true;
2)	case o of
2)	four_cases(put1): begin major('put',o-put1+1:0,' ',p:0); goto done;
2)		end;
2)	@t\4@>@<Cases for vertical motion@>@;
2)	@t\4@>@<Cases for fonts@>@;
2)	four_cases(xxx1): @<Translate an |xxx| command and |goto done|@>;
2)	pre: begin error('preamble command within a page!'); goto 9998;
2)		end;
2)	@.preamble command within a page@>
2)	post,post_post: begin error('postamble command within a page!'); goto 9998;
2)	@.postamble command within a page@>
2)		end;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11

2)	othercases begin error('undefined command ',o:0,'!');
2)		goto done;
2)	@.undefined command@>
2)		end
2)	endcases;
2)	move_down: @<Finish a command that sets |v←v+p|, then |goto done|@>;
2)	change_font: @<Finish a command that changes the current font,
2)		then |goto done|@>;
2)	9998: pure←false;
2)	done: special_cases←pure;
2)	end;
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1868L
1)	  end;
1)	bop: begin error('bop occurred before eop'); goto 9998;
1)	@.bop occurred before eop@>
1)	  end;
1)	eop: begin major('eop');
1)	  if s<>0 then error('stack not empty at end of page (level ',
1)	    s:0,')!');
1)	@.stack not empty...@>
1)	  do←page:=true; print←ln(' '); goto 9999;
1)	  end;
1)	push: begin major('push');
1)	  if s=max←s←so←far then
1)	    begin max←s←so←far:=s+1;
1)	    if s=max←s then error('deeper than claimed in postamble!');
1)	@.deeper than claimed...@>
1)	@.push deeper than claimed...@>
1)	    if s=stack←size then
1)	      begin error('DVItype capacity exceeded (stack size=',
1)	        stack←size:0,')'); goto 9998;
1)	      end;
1)	    end;
1)	  hstack[s]:=h; vstack[s]:=v; wstack[s]:=w;
1)	  xstack[s]:=x; ystack[s]:=y; zstack[s]:=z;
1)	  hhstack[s]:=hh; vvstack[s]:=vv; incr(s); ss:=s-1; goto show←state;
1)	  end;
1)	pop: begin major('pop');
1)	  if s=0 then error('(illegal at level zero)!')
1)	  else  begin decr(s); hh:=hhstack[s]; vv:=vvstack[s];
1)	    h:=hstack[s]; v:=vstack[s]; w:=wstack[s];
1)	    x:=xstack[s]; y:=ystack[s]; z:=zstack[s];
1)	    end;
1)	  ss:=s; goto show←state;
1)	  end;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11

1)	@ Rounding to the nearest pixel is best done in the manner shown here, so as
**** File 2) DVITYP.WEB[PAS,DEK]/11P/221L
2)		end;
2)	bop: begin error('bop occurred before eop'); goto 9998;
2)	@.bop occurred before eop@>
2)		end;
2)	eop: begin major('eop');
2)		if s≠0 then error('stack not empty at end of page (level ',
2)			s:0,')!');
2)	@.stack not empty...@>
2)		do_page←true; print_ln(' '); goto 9999;
2)		end;
2)	push: begin major('push');
2)		if s=max_s_so_far then
2)			begin max_s_so_far←s+1;
2)			if s=max_s then error('deeper than claimed in postamble!');
2)	@.deeper than claimed...@>
2)	@.push deeper than claimed...@>
2)			if s=stack_size then
2)				begin error('DVItype capacity exceeded (stack size=',
2)					stack_size:0,')'); goto 9998;
2)				end;
2)			end;
2)		hstack[s]←h; vstack[s]←v; wstack[s]←w;
2)		xstack[s]←x; ystack[s]←y; zstack[s]←z;
2)		hhstack[s]←hh; vvstack[s]←vv; incr(s); ss←s-1; goto show_state;
2)		end;
2)	pop: begin major('pop');
2)		if s=0 then error('(illegal at level zero)!')
2)		else	begin decr(s); hh←hhstack[s]; vv←vvstack[s];
2)			h←hstack[s]; v←vstack[s]; w←wstack[s];
2)			x←xstack[s]; y←ystack[s]; z←zstack[s];
2)			end;
2)		ss←s; goto show_state;
2)		end;
2)	@ Rounding to the nearest pixel is best done in the manner shown here, so as
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1909L
1)	@d out←space(#)==if abs(p)>=font←space[cur←font] then
1)	    begin out←text(" "); hh:=pixel←round(h+p);
1)	    end
1)	  else hh:=hh+pixel←round(p);
1)	  minor(#,' ',p:0); q:=p; goto move←right
1)	@<Cases for horizontal motion@>=
1)	four←cases(right1):begin out←space('right',o-right1+1:0);
1)	  end;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11

1)	w0,four←cases(w1):begin w:=p; out←space('w',o-w0:0);
1)	  end;
1)	x0,four←cases(x1):begin x:=p; out←space('x',o-x0:0);
1)	  end;
1)	@ Vertical motion is done similarly, but with the threshold between
**** File 2) DVITYP.WEB[PAS,DEK]/11P/262L
2)	@d out_space(#)==if abs(p)≥font_space[cur_font] then
2)			begin out_text(" "); hh←pixel_round(h+p);
2)			end
2)		else hh←hh+pixel_round(p);
2)		minor(#,' ',p:0); q←p; goto move_right
2)	@<Cases for horizontal motion@>=
2)	four_cases(right1):begin out_space('right',o-right1+1:0);
2)		end;
2)	w0,four_cases(w1):begin w←p; out_space('w',o-w0:0);
2)		end;
2)	x0,four_cases(x1):begin x←p; out_space('x',o-x0:0);
2)		end;
2)	@ Vertical motion is done similarly, but with the threshold between
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1928L
1)	@d out←vmove(#)==if abs(p)>=5*font←space[cur←font] then vv:=pixel←round(v+p)
1)	  else vv:=vv+pixel←round(p);
1)	  major(#,' ',p:0); goto move←down
1)	@<Cases for vertical motion@>=
1)	four←cases(down1):begin out←vmove('down',o-down1+1:0);
1)	  end;
1)	y0,four←cases(y1):begin y:=p; out←vmove('y',o-y0:0);
1)	  end;
1)	z0,four←cases(z1):begin z:=p; out←vmove('z',o-z0:0);
1)	  end;
1)	@ @<Cases for fonts@>=
1)	sixty←four←cases(fnt←num←0): begin major('fntnum',p:0);
1)	  goto change←font;
1)	  end;
1)	four←cases(fnt1): begin major('fnt',o-fnt1+1:0,' ',p:0);
1)	  goto change←font;
1)	  end;
1)	four←cases(fnt←def1): begin major('fntdef',o-fnt←def1+1:0,' ',p:0);
1)	  define←font(p); goto done;
1)	  end;
1)	@ @<Translate an |xxx| command and |goto done|@>=
1)	begin major('xxx'''); bad←char:=false;
1)	for k:=1 to p do
1)	  begin q:=get←byte;
1)	  if (q>="!")and(q<="~") then
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11

1)	    begin if showing then print(xchr[q]);
1)	    end
1)	  else bad←char:=true;
1)	  end;
1)	if showing then print('''');
1)	if bad←char then error('non-ascii character in xxx command!');
1)	@.non-ascii character...@>
**** File 2) DVITYP.WEB[PAS,DEK]/11P/281L
2)	@d out_vmove(#)==if abs(p)≥5*font_space[cur_font] then vv←pixel_round(v+p)
2)		else vv←vv+pixel_round(p);
2)		major(#,' ',p:0); goto move_down
2)	@<Cases for vertical motion@>=
2)	four_cases(down1):begin out_vmove('down',o-down1+1:0);
2)		end;
2)	y0,four_cases(y1):begin y←p; out_vmove('y',o-y0:0);
2)		end;
2)	z0,four_cases(z1):begin z←p; out_vmove('z',o-z0:0);
2)		end;
2)	@ @<Cases for fonts@>=
2)	sixty_four_cases(fnt_num_0): begin major('fntnum',p:0);
2)		goto change_font;
2)		end;
2)	four_cases(fnt1): begin major('fnt',o-fnt1+1:0,' ',p:0);
2)		goto change_font;
2)		end;
2)	four_cases(fnt_def1): begin major('fntdef',o-fnt_def1+1:0,' ',p:0);
2)		define_font(p); goto done;
2)		end;
2)	@ @<Translate an |xxx| command and |goto done|@>=
2)	begin major('xxx'''); bad_char←false;
2)	for k←1 to p do
2)		begin q←get_byte;
2)		if (q≥"!")∧(q≤"~") then
2)			begin if showing then print(xchr[q]);
2)			end
2)		else bad_char←true;
2)		end;
2)	if showing then print('''');
2)	if bad_char then error('non-ascii character in xxx command!');
2)	@.non-ascii character...@>
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/1966L
1)	@ @<Translate a |set←char|...@>=
1)	begin if (o>" ")and(o<="~") then
1)	  begin out←text(p); minor('setchar',p:0);
1)	  end
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11

1)	else major('setchar',p:0);
1)	goto fin←set;
1)	end
1)	@ @<Finish a command that either sets or puts a character...@>=
1)	if font←ec[cur←font]=256 then p:=256; {width computation for oriental fonts}
1)	if (p<font←bc[cur←font])or(p>font←ec[cur←font]) then q:=invalid←width
1)	else q:=char←width(cur←font)(p);
1)	if q=invalid←width then
1)	  begin error('character ',p:0,' invalid in font ');
1)	@.character $c$ invalid...@>
1)	  print←font(cur←font);
1)	  if cur←font<>nf then print('!');
1)	  end;
1)	if o>=put1 then goto done;
1)	if q=invalid←width then q:=0
1)	else hh:=hh+char←pixel←width(cur←font)(p);
1)	goto move←right
1)	@ @<Finish a command that either sets or puts a rule...@>=
1)	q:=signed←quad;
1)	if showing then
1)	  begin print(' height ',p:0,', width ',q:0);
1)	  if (p<=0)or(q<=0) then print(' (invisible)')
1)	  else print(' (',rule←pixels(p):0,'x',rule←pixels(q):0,' pixels)');
1)	  end;
1)	if o=put←rule then goto done;
1)	print←ln(' ');
1)	hh:=hh+rule←pixels(q); goto move←right
1)	@ Since \.{DVItype} is intended to diagnose strange errors, it checks
**** File 2) DVITYP.WEB[PAS,DEK]/11P/319L
2)	@ @<Translate a |set_char|...@>=
2)	begin if (o>" ")∧(o≤"~") then
2)		begin out_text(p); minor('setchar',p:0);
2)		end
2)	else major('setchar',p:0);
2)	goto fin_set;
2)	end
2)	@ @<Finish a command that either sets or puts a character...@>=
2)	if font_ec[cur_font]=256 then p←256; {width computation for oriental fonts}
2)	if (p<font_bc[cur_font])∨(p>font_ec[cur_font]) then q←invalid_width
2)	else q←char_width(cur_font)(p);
2)	if q=invalid_width then
2)		begin error('character ',p:0,' invalid in font ');
2)	@.character $c$ invalid...@>
2)		print_font(cur_font);
2)		if cur_font≠nf then print('!');
2)		end;
2)	if o≥put1 then goto done;
2)	if q=invalid_width then q←0
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11

2)	else hh←hh+char_pixel_width(cur_font)(p);
2)	goto move_right
2)	@ @<Finish a command that either sets or puts a rule...@>=
2)	q←signed_quad;
2)	if showing then
2)		begin print(' height ',p:0,', width ',q:0);
2)		if (p≤0)∨(q≤0) then print(' (invisible)')
2)		else print(' (',rule_pixels(p):0,'x',rule_pixels(q):0,' pixels)');
2)		end;
2)	if o=put_rule then goto done;
2)	print_ln(' ');
2)	hh←hh+rule_pixels(q); goto move_right
2)	@ Since \.{DVItype} is intended to diagnose strange errors, it checks
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/2006L
1)	@<Finish a command that sets |h:=h+q|, then |goto done|@>=
1)	if (h>0)and(q>0) then if h>infinity-q then
1)	  begin error('arithmetic overflow! parameter changed from ',
1)	@.arithmetic overflow...@>
1)	    q:0,' to ',infinity-h:0);
1)	  q:=infinity-h;
1)	  end;
1)	if (h<0)and(q<0) then if -h>q+infinity then
1)	  begin error('arithmetic overflow! parameter changed from ',
1)	    q:0, ' to ',(-h)-infinity:0);
1)	  q:=(-h)-infinity;
1)	  end;
1)	if showing then
1)	  begin print(' h:=',h:0);
1)	  if q>=0 then print('+');
1)	  print(q:0,'=',h+q:0,', hh:=',hh:0);
1)	  end;
1)	h:=h+q;
1)	if abs(h)>max←h←so←far then
1)	  begin max←h←so←far:=abs(h);
1)	  if abs(h)>max←h then error('warning: |h|>',max←h←so←far:0,'!');
1)	@.warning: |h|...@>
1)	  end;
1)	goto done
1)	@ @<Finish a command that sets |v:=v+p|, then |goto done|@>=
1)	if (v>0)and(p>0) then if v>infinity-p then
1)	  begin error('arithmetic overflow! parameter changed from ',
1)	@.arithmetic overflow...@>
1)	    p:0,' to ',infinity-v:0);
1)	  p:=infinity-v;
1)	  end;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11

1)	if (v<0)and(p<0) then if -v>p+infinity then
1)	  begin error('arithmetic overflow! parameter changed from ',
1)	    p:0, ' to ',(-v)-infinity:0);
1)	  p:=(-v)-infinity;
1)	  end;
1)	if showing then
1)	  begin print(' v:=',v:0);
1)	  if p>=0 then print('+');
1)	  print(p:0,'=',v+p:0,', vv:=',vv:0);
1)	  end;
1)	v:=v+p;
1)	if abs(v)>max←v←so←far then
1)	  begin max←v←so←far:=abs(v);
1)	  if abs(v)>max←v then error('warning: |v|>',max←v←so←far:0,'!');
1)	@.warning: |v|...@>
1)	  end;
1)	goto done
**** File 2) DVITYP.WEB[PAS,DEK]/11P/359L
2)	@<Finish a command that sets |h←h+q|, then |goto done|@>=
2)	if (h>0)∧(q>0) then if h>infinity-q then
2)		begin error('arithmetic overflow! parameter changed from ',
2)	@.arithmetic overflow...@>
2)			q:0,' to ',infinity-h:0);
2)		q←infinity-h;
2)		end;
2)	if (h<0)∧(q<0) then if -h>q+infinity then
2)		begin error('arithmetic overflow! parameter changed from ',
2)			q:0, ' to ',(-h)-infinity:0);
2)		q←(-h)-infinity;
2)		end;
2)	if showing then
2)		begin print(' h:=',h:0);
2)		if q≥0 then print('+');
2)		print(q:0,'=',h+q:0,', hh:=',hh:0);
2)		end;
2)	h←h+q;
2)	if abs(h)>max_h_so_far then
2)		begin max_h_so_far←abs(h);
2)		if abs(h)>max_h then error('warning: |h|>',max_h_so_far:0,'!');
2)	@.warning: |h|...@>
2)		end;
2)	goto done
2)	@ @<Finish a command that sets |v←v+p|, then |goto done|@>=
2)	if (v>0)∧(p>0) then if v>infinity-p then
2)		begin error('arithmetic overflow! parameter changed from ',
2)	@.arithmetic overflow...@>
2)			p:0,' to ',infinity-v:0);
2)		p←infinity-v;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11

2)		end;
2)	if (v<0)∧(p<0) then if -v>p+infinity then
2)		begin error('arithmetic overflow! parameter changed from ',
2)			p:0, ' to ',(-v)-infinity:0);
2)		p←(-v)-infinity;
2)		end;
2)	if showing then
2)		begin print(' v:=',v:0);
2)		if p≥0 then print('+');
2)		print(p:0,'=',v+p:0,', vv:=',vv:0);
2)		end;
2)	v←v+p;
2)	if abs(v)>max_v_so_far then
2)		begin max_v_so_far←abs(v);
2)		if abs(v)>max_v then error('warning: |v|>',max_v_so_far:0,'!');
2)	@.warning: |v|...@>
2)		end;
2)	goto done
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/2058L
1)	  begin print←ln(' ');
1)	  print('level ',ss:0,':(h=',h:0,',v=',v:0,
1)	    ',w=',w:0,',x=',x:0,',y=',y:0,',z=',z:0,
1)	    ',hh=',hh:0,',vv=',vv:0,')');
1)	  end;
1)	goto done
1)	@ @<Finish a command that changes the current font...@>=
1)	font←num[nf]:=p; cur←font:=0;
1)	while font←num[cur←font]<>p do incr(cur←font);
1)	if showing then
1)	  begin print(' current font is '); print←font(cur←font);
1)	  end;
1)	goto done
1)	@* Skipping pages.
1)	A routine that's much simpler than |do←page| is used to pass over
1)	pages that are not being translated. The |skip←pages| subroutine
1)	is assumed to begin just after the preamble has been read, or just
**** File 2) DVITYP.WEB[PAS,DEK]/11P/411L
2)		begin print_ln(' ');
2)		print('level ',ss:0,':(h=',h:0,',v=',v:0,
2)			',w=',w:0,',x=',x:0,',y=',y:0,',z=',z:0,
2)			',hh=',hh:0,',vv=',vv:0,')');
2)		end;
2)	goto done
2)	@ @<Finish a command that changes the current font...@>=
2)	font_num[nf]←p; cur_font←0;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,11

2)	while font_num[cur_font]≠p do incr(cur_font);
2)	if showing then
2)		begin print(' current font is '); print_font(cur_font);
2)		end;
2)	goto done
2)	@* Skipping pages.
2)	A routine that's much simpler than |do_page| is used to pass over
2)	pages that are not being translated. The |skip_pages| subroutine
2)	is assumed to begin just after the preamble has been read, or just
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/2081L
1)	@p procedure skip←pages;
1)	label 9999; {end of this subroutine}
**** File 2) DVITYP.WEB[PAS,DEK]/12P/9L
2)	@p procedure skip_pages;
2)	label 9999; {end of this subroutine}
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/2085L
1)	@!down←the←drain:integer; {garbage}
1)	begin showing:=false;
1)	while true do
1)	  begin if eof(dvi←file) then abort('the file ended prematurely!');
1)	@.the file ended prematurely@>
1)	  k:=get←byte;
1)	  p:=first←par(k);
1)	  case k of
1)	  bop: begin @<Pass a |bop| command, setting up the |count| array@>;
1)	    if not started and start←match then
1)	      begin started:=true; goto 9999;
1)	      end;
1)	    end;
1)	  set←rule,put←rule: down←the←drain:=signed←quad;
1)	  fnt←def1,fnt←def1+1,fnt←def1+2,fnt←def1+3: define←font(down←the←drain);
1)	  xxx1,xxx1+1,xxx1+2,xxx1+3: while p>0 do
1)	    begin down←the←drain:=get←byte; decr(p);
1)	    end;
1)	  post: begin in←postamble:=true; goto 9999;
1)	    end;
1)	  othercases do←nothing
1)	  endcases;
1)	  end;
1)	9999:end;
1)	@ Global variables called |old←backpointer| and |new←backpointer|
1)	are used to check whether the back pointers are properly set up.
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,12

**** File 2) DVITYP.WEB[PAS,DEK]/12P/13L
2)	@!down_the_drain:integer; {garbage}
2)	begin showing←false;
2)	while true do
2)		begin if eof(dvi_file) then abort('the file ended prematurely!');
2)	@.the file ended prematurely@>
2)		k←get_byte;
2)		p←first_par(k);
2)		case k of
2)		bop: begin @<Pass a |bop| command, setting up the |count| array@>;
2)			if ¬ started ∧ start_match then
2)				begin started←true; goto 9999;
2)				end;
2)			end;
2)		set_rule,put_rule: down_the_drain←signed_quad;
2)		fnt_def1,fnt_def1+1,fnt_def1+2,fnt_def1+3: define_font(down_the_drain);
2)		xxx1,xxx1+1,xxx1+2,xxx1+3: while p>0 do
2)			begin down_the_drain←get_byte; decr(p);
2)			end;
2)		post: begin in_postamble←true; goto 9999;
2)			end;
2)		othercases do_nothing
2)		endcases;
2)		end;
2)	9999:end;
2)	@ Global variables called |old_backpointer| and |new_backpointer|
2)	are used to check whether the back pointers are properly set up.
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/2115L
1)	@!old←backpointer:integer; {the previous |bop| command location}
1)	@!new←backpointer:integer; {the current |bop| command location}
1)	@!started:boolean; {has the starting page been found?}
1)	@ @<Set init...@>=
1)	old←backpointer:=-1; started:=false;
1)	@ @<Pass a |bop|...@>=
1)	new←backpointer:=cur←loc-1; incr(page←count);
1)	for k:=0 to 9 do count[k]:=signed←quad;
1)	if signed←quad<>old←backpointer
1)	  then print←ln('backpointer in byte ',cur←loc-4:0,
1)	    ' should be ',old←backpointer:0,'!');
1)	@.backpointer...should be p@>
1)	old←backpointer:=new←backpointer
1)	@* Using the backpointers.
1)	The routines in this section of the program are brought into play only
1)	if |random←reading| is |true| (and only if |out←mode=the←works|).
1)	First comes a routine that illustrates how to find the postamble quickly.
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,12

1)	@<Find the postamble, working back from the end@>=
1)	n:=dvi←length;
1)	if n<57 then bad←dvi('only ',n:0,' bytes long');
1)	@.only n bytes long@>
1)	m:=n-4;
1)	repeat if m=0 then bad←dvi('all 223s');
1)	@.all 223s@>
1)	move←to←byte(m); k:=get←byte; decr(m);
1)	until k<>223;
1)	if k<>id←byte then bad←dvi('ID byte is ',k:0);
1)	@.ID byte is wrong@>
1)	move←to←byte(m-3); q:=signed←quad;
1)	if (q<0)or(q>m-36) then bad←dvi('post pointer ',q:0,' at byte ',m-3:0);
1)	@.post pointer is wrong@>
1)	move←to←byte(q); k:=get←byte;
1)	if k<>post then bad←dvi('byte ',q:0,' is not post');
1)	@.byte n is not post@>
1)	post←loc:=q; first←backpointer:=signed←quad
1)	@ Note that the last steps of the above code save the locations of the
**** File 2) DVITYP.WEB[PAS,DEK]/12P/43L
2)	@!old_backpointer:integer; {the previous |bop| command location}
2)	@!new_backpointer:integer; {the current |bop| command location}
2)	@!started:boolean; {has the starting page been found?}
2)	@ @<Set init...@>=
2)	old_backpointer←-1; started←false;
2)	@ @<Pass a |bop|...@>=
2)	new_backpointer←cur_loc-1; incr(page_count);
2)	for k←0 to 9 do count[k]←signed_quad;
2)	if signed_quad≠old_backpointer
2)		then print_ln('backpointer in byte ',cur_loc-4:0,
2)			' should be ',old_backpointer:0,'!');
2)	@.backpointer...should be p@>
2)	old_backpointer←new_backpointer
2)	@* Using the backpointers.
2)	The routines in this section of the program are brought into play only
2)	if |random_reading| is |true| (and only if |out_mode=the_works|).
2)	First comes a routine that illustrates how to find the postamble quickly.
2)	@<Find the postamble, working back from the end@>=
2)	n←dvi_length;
2)	if n<57 then bad_dvi('only ',n:0,' bytes long');
2)	@.only n bytes long@>
2)	m←n-4;
2)	repeat if m=0 then bad_dvi('all 223s');
2)	@.all 223s@>
2)	move_to_byte(m); k←get_byte; decr(m);
2)	until k≠223;
2)	if k≠id_byte then bad_dvi('ID byte is ',k:0);
2)	@.ID byte is wrong@>
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,12

2)	move_to_byte(m-3); q←signed_quad;
2)	if (q<0)∨(q>m-36) then bad_dvi('post pointer ',q:0,' at byte ',m-3:0);
2)	@.post pointer is wrong@>
2)	move_to_byte(q); k←get_byte;
2)	if k≠post then bad_dvi('byte ',q:0,' is not post');
2)	@.byte n is not post@>
2)	post_loc←q; first_backpointer←signed_quad
2)	@ Note that the last steps of the above code save the locations of the
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/2160L
1)	@!post←loc:integer; {byte location where the postamble begins}
1)	@!first←backpointer:integer; {the pointer following |post|}
1)	@!start←loc:integer; {byte location of the first page to process}
1)	@ The next little routine shows how the backpointers can be followed
**** File 2) DVITYP.WEB[PAS,DEK]/13P/30L
2)	@!post_loc:integer; {byte location where the postamble begins}
2)	@!first_backpointer:integer; {the pointer following |post|}
2)	@!start_loc:integer; {byte location of the first page to process}
2)	@ The next little routine shows how the backpointers can be followed
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/2172L
1)	q:=post←loc; p:=first←backpointer; start←loc:=-1;
1)	if p>=0 then
1)	  repeat {now |q| points to a |post| or |bop| command; |p>=0| is prev pointer}
1)	  if p>q-46 then
1)	    bad←dvi('page link ',p:0,' after byte ',q:0);
1)	@.page link wrong...@>
1)	  q:=p; move←to←byte(q); k:=get←byte;
1)	  if k=bop then incr(page←count)
1)	  else bad←dvi('byte ',q:0,' is not bop');
1)	@.byte n is not bop@>
1)	  for k:=0 to 9 do count[k]:=signed←quad;
1)	  if start←match then start←loc:=q;
1)	  p:=signed←quad;
1)	  until p<0;
1)	if page←count<>total←pages then
1)	  print←ln('there are really ',page←count:0,' pages, not ',total←pages:0,'!');
1)	@.there are really n pages@>
1)	if start←loc<0 then abort('starting page number could not be found!');
1)	move←to←byte(start←loc+1); old←backpointer:=start←loc;
1)	for k:=0 to 9 do count[k]:=signed←quad;
1)	p:=signed←quad; started:=true
1)	@* Reading the postamble.
**** File 2) DVITYP.WEB[PAS,DEK]/13P/42L
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,13

2)	q←post_loc; p←first_backpointer; start_loc←-1;
2)	if p≥0 then
2)		repeat {now |q| points to a |post| or |bop| command; |p≥0| is prev pointer}
2)		if p>q-46 then
2)			bad_dvi('page link ',p:0,' after byte ',q:0);
2)	@.page link wrong...@>
2)		q←p; move_to_byte(q); k←get_byte;
2)		if k=bop then incr(page_count)
2)		else bad_dvi('byte ',q:0,' is not bop');
2)	@.byte n is not bop@>
2)		for k←0 to 9 do count[k]←signed_quad;
2)		if start_match then start_loc←q;
2)		p←signed_quad;
2)		until p<0;
2)	if page_count≠total_pages then
2)		print_ln('there are really ',page_count:0,' pages, not ',total_pages:0,'!');
2)	@.there are really n pages@>
2)	if start_loc<0 then abort('starting page number could not be found!');
2)	move_to_byte(start_loc+1); old_backpointer←start_loc;
2)	for k←0 to 9 do count[k]←signed_quad;
2)	p←signed_quad; started←true
2)	@* Reading the postamble.
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/2200L
1)	@p procedure read←postamble;
1)	var k:integer; {loop index}
1)	@!p,@!q,@!m:integer; {general purpose registers}
1)	begin showing:=false; post←loc:=cur←loc-5;
1)	print←ln('Postamble starts at byte ',post←loc:0,'.');
1)	@.Postamble starts at byte n@>
1)	if signed←quad<>numerator then
1)	  print←ln('numerator doesn''t match the preamble!');
1)	@.numerator doesn't match@>
1)	if signed←quad<>denominator then
1)	  print←ln('denominator doesn''t match the preamble!');
1)	@.denominator doesn't match@>
1)	if signed←quad<>mag then if new←mag=0 then
1)	  print←ln('magnification doesn''t match the preamble!');
1)	@.magnification doesn't match@>
1)	max←v:=signed←quad; max←h:=signed←quad;@/
1)	print('maxv=',max←v:0,', maxh=',max←h:0);@/
1)	max←s:=get←two←bytes; total←pages:=get←two←bytes;@/
1)	print←ln(', maxstackdepth=',max←s:0,', totalpages=',total←pages:0);
1)	if out←mode<the←works then
1)	  @<Compare the \\{lust} parameters with the accumulated facts@>;
1)	@<Process the font definitions of the postamble@>;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,14

**** File 2) DVITYP.WEB[PAS,DEK]/14P/7L
2)	@p procedure read_postamble;
2)	var k:integer; {loop index}
2)	@!p,@!q,@!m:integer; {general purpose registers}
2)	begin showing←false; post_loc←cur_loc-5;
2)	print_ln('Postamble starts at byte ',post_loc:0,'.');
2)	@.Postamble starts at byte n@>
2)	if signed_quad≠numerator then
2)		print_ln('numerator doesn''t match the preamble!');
2)	@.numerator doesn't match@>
2)	if signed_quad≠denominator then
2)		print_ln('denominator doesn''t match the preamble!');
2)	@.denominator doesn't match@>
2)	if signed_quad≠mag then if new_mag=0 then
2)		print_ln('magnification doesn''t match the preamble!');
2)	@.magnification doesn't match@>
2)	max_v←signed_quad; max_h←signed_quad;@/
2)	print('maxv=',max_v:0,', maxh=',max_h:0);@/
2)	max_s←get_two_bytes; total_pages←get_two_bytes;@/
2)	print_ln(', maxstackdepth=',max_s:0,', totalpages=',total_pages:0);
2)	if out_mode<the_works then
2)		@<Compare the \\{lust} parameters with the accumulated facts@>;
2)	@<Process the font definitions of the postamble@>;
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/2226L
1)	begin if max←v<max←v←so←far then
1)	  print←ln('warning: observed maxv was ',max←v←so←far:0);
1)	@.warning: observed maxv...@>
1)	@.observed maxv was x@>
1)	if max←h<max←h←so←far then
1)	  print←ln('warning: observed maxh was ',max←h←so←far:0);
1)	@.warning: observed maxh...@>
1)	@.observed maxh was x@>
1)	if max←s<max←s←so←far then
1)	  print←ln('warning: observed maxstackdepth was ',max←s←so←far:0);
1)	@.warning: observed maxstack...@>
1)	@.observed maxstackdepth was x@>
1)	if page←count<>total←pages then
1)	  print←ln('there are really ',page←count:0,' pages, not ',total←pages:0,'!');
1)	end
1)	@.there are really n pages@>
1)	@ When we get to the present code, the |post←post| command has
1)	just been read.
1)	@<Make sure that the end of the file is well-formed@>=
1)	q:=signed←quad;
1)	if q<>post←loc then
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,14

1)	  print←ln('bad postamble pointer in byte ',cur←loc-4:0,'!');
1)	@.bad postamble pointer@>
1)	m:=get←byte;
1)	if m<>id←byte then print←ln('identification in byte ',cur←loc-1:0,
1)	@.identification...should be n@>
1)	    ' should be ',id←byte:0,'!');
1)	k:=cur←loc; m:=223;
1)	while (m=223)and not eof(dvi←file) do m:=get←byte;
1)	if not eof(dvi←file) then abort('signature in byte ',cur←loc-1:0,
1)	@.signature...should be...@>
1)	    ' should be 223!')
1)	else if cur←loc<k+4 then
1)	  print←ln('not enough signature bytes at end of file (',
1)	@.not enough signature bytes...@>
1)	    cur←loc-k:0,')');
1)	@ @<Process the font definitions...@>=
1)	repeat k:=get←byte;
1)	if (k>=fnt←def1)and(k<fnt←def1+4) then
1)	  begin p:=first←par(k); define←font(p); print←ln(' '); k:=nop;
1)	  end;
1)	until k<>nop;
1)	if k<>post←post then
1)	  print←ln('byte ',cur←loc-1:0,' is not postpost!')
1)	@.byte n is not postpost@>
**** File 2) DVITYP.WEB[PAS,DEK]/14P/33L
2)	begin if max_v<max_v_so_far then
2)		print_ln('warning: observed maxv was ',max_v_so_far:0);
2)	@.warning: observed maxv...@>
2)	@.observed maxv was x@>
2)	if max_h<max_h_so_far then
2)		print_ln('warning: observed maxh was ',max_h_so_far:0);
2)	@.warning: observed maxh...@>
2)	@.observed maxh was x@>
2)	if max_s<max_s_so_far then
2)		print_ln('warning: observed maxstackdepth was ',max_s_so_far:0);
2)	@.warning: observed maxstack...@>
2)	@.observed maxstackdepth was x@>
2)	if page_count≠total_pages then
2)		print_ln('there are really ',page_count:0,' pages, not ',total_pages:0,'!');
2)	end
2)	@.there are really n pages@>
2)	@ When we get to the present code, the |post_post| command has
2)	just been read.
2)	@<Make sure that the end of the file is well-formed@>=
2)	q←signed_quad;
2)	if q≠post_loc then
2)		print_ln('bad postamble pointer in byte ',cur_loc-4:0,'!');
2)	@.bad postamble pointer@>
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,14

2)	m←get_byte;
2)	if m≠id_byte then print_ln('identification in byte ',cur_loc-1:0,
2)	@.identification...should be n@>
2)			' should be ',id_byte:0,'!');
2)	k←cur_loc; m←223;
2)	while (m=223)∧ not eof(dvi_file) do m←get_byte;
2)	if not eof(dvi_file) then abort('signature in byte ',cur_loc-1:0,
2)	@.signature...should be...@>
2)			' should be 223!')
2)	else if cur_loc<k+4 then
2)		print_ln('not enough signature bytes at end of file (',
2)	@.not enough signature bytes...@>
2)			cur_loc-k:0,')');
2)	@ @<Process the font definitions...@>=
2)	repeat k←get_byte;
2)	if (k≥fnt_def1)∧(k<fnt_def1+4) then
2)		begin p←first_par(k); define_font(p); print_ln(' '); k←nop;
2)		end;
2)	until k≠nop;
2)	if k≠post_post then
2)		print_ln('byte ',cur_loc-1:0,' is not postpost!')
2)	@.byte n is not postpost@>
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/2282L
1)	if out←mode=the←works then {|random←reading=true|}
1)	  begin @<Find the postamble, working back from the end@>;
1)	  in←postamble:=true; read←postamble; in←postamble:=false;
1)	  @<Count the pages and move to the starting page@>;
1)	  end
1)	else skip←pages;
1)	if not in←postamble then @<Translate up to |max←pages| pages@>;
1)	if out←mode<the←works then
1)	  begin if not in←postamble then skip←pages;
1)	  if signed←quad<>old←backpointer then
1)	    print←ln('backpointer in byte ',cur←loc-4:0,
1)	      ' should be ',old←backpointer:0,'!');
1)	@.backpointer...should be p@>
1)	  read←postamble;
1)	  end;
1)	final←end:end.
1)	@ The main program needs a few global variables in order to do its work.
**** File 2) DVITYP.WEB[PAS,DEK]/15P/8L
2)	if out_mode=the_works then {|random_reading=true|}
2)		begin @<Find the postamble, working back from the end@>;
2)		in_postamble←true; read_postamble; in_postamble←false;
2)		@<Count the pages and move to the starting page@>;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,15

2)		end
2)	else skip_pages;
2)	if ¬ in_postamble then @<Translate up to |max_pages| pages@>;
2)	if out_mode<the_works then
2)		begin if not in_postamble then skip_pages;
2)		if signed_quad≠old_backpointer then
2)			print_ln('backpointer in byte ',cur_loc-4:0,
2)				' should be ',old_backpointer:0,'!');
2)	@.backpointer...should be p@>
2)		read_postamble;
2)		end;
2)	final_end:end.
2)	@ The main program needs a few global variables in order to do its work.
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/2309L
1)	open←dvi←file;
1)	p:=get←byte; {fetch the first byte}
1)	if p<>pre then bad←dvi('First byte isn''t start of preamble!');
1)	@.First byte isn't...@>
1)	p:=get←byte; {fetch the identification byte}
1)	if p<>id←byte then
1)	  print←ln('identification in byte 1 should be ',id←byte:0,'!');
1)	@.identification...should be n@>
1)	@<Compute the conversion factor@>;
1)	p:=get←byte; {fetch the length of the introductory comment}
1)	print('''');
1)	while p>0 do
1)	  begin decr(p); print(xchr[get←byte]);
1)	  end;
1)	print←ln('''')
1)	@ The conversion factor |conv| is figured as follows: There are exactly
**** File 2) DVITYP.WEB[PAS,DEK]/15P/35L
2)	open_dvi_file;
2)	p←get_byte; {fetch the first byte}
2)	if p≠pre then bad_dvi('First byte isn''t start of preamble!');
2)	@.First byte isn't...@>
2)	p←get_byte; {fetch the identification byte}
2)	if p≠id_byte then
2)		print_ln('identification in byte 1 should be ',id_byte:0,'!');
2)	@.identification...should be n@>
2)	@<Compute the conversion factor@>;
2)	p←get_byte; {fetch the length of the introductory comment}
2)	print('''');
2)	while p>0 do
2)		begin decr(p); print(xchr[get_byte]);
2)		end;
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,15

2)	print_ln('''')
2)	@ The conversion factor |conv| is figured as follows: There are exactly
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/2331L
1)	numerator:=signed←quad; denominator:=signed←quad;
1)	if numerator<=0 then bad←dvi('numerator is ',numerator:0);
1)	@.numerator is wrong@>
1)	if denominator<=0 then bad←dvi('denominator is ',denominator:0);
1)	@.denominator is wrong@>
1)	print←ln('numerator/denominator=',numerator:0,'/',denominator:0);
1)	conv:=(numerator/254000.0)*(resolution/denominator);
1)	mag:=signed←quad;
1)	if new←mag>0 then mag:=new←mag
1)	else if mag<=0 then bad←dvi('magnification is ',mag:0);
1)	@.magnification is wrong@>
1)	true←conv:=conv; conv:=true←conv*(mag/1000.0);
1)	print←ln('magnification=',mag:0,'; ',conv:16:8,' pixels per DVI unit')
1)	@ The code shown here uses a convention that has proved to be useful:
**** File 2) DVITYP.WEB[PAS,DEK]/15P/57L
2)	numerator←signed_quad; denominator←signed_quad;
2)	if numerator≤0 then bad_dvi('numerator is ',numerator:0);
2)	@.numerator is wrong@>
2)	if denominator≤0 then bad_dvi('denominator is ',denominator:0);
2)	@.denominator is wrong@>
2)	print_ln('numerator/denominator=',numerator:0,'/',denominator:0);
2)	conv←(numerator/254000.0)*(resolution/denominator);
2)	mag←signed_quad;
2)	if new_mag>0 then mag←new_mag
2)	else if mag≤0 then bad_dvi('magnification is ',mag:0);
2)	@.magnification is wrong@>
2)	true_conv←conv; conv←true_conv*(mag/1000.0);
2)	print_ln('magnification=',mag:0,'; ',conv:16:8,' pixels per DVI unit')
2)	@ The code shown here uses a convention that has proved to be useful:
***************


**** File 1) DVITYP.WEB[WEB,ALS]/1P/2353L
1)	begin while max←pages>0 do
1)	  begin decr(max←pages);
1)	  print←ln(' '); print(cur←loc-45:0,': beginning of page ');
1)	  for k:=0 to start←vals do
1)	    begin print(count[k]:0);
1)	    if k<start←vals then print('.')
1)	    else print←ln(' ');
1)	    end;
1)	  if not do←page then abort('page ended unexpectedly!');
  1) DVITYP.WEB[WEB,ALS] and 2) DVITYP.WEB[PAS,DEK]	9-16-82 09:28	pages 1,15

1)	@.page ended unexpectedly@>
1)	  repeat k:=get←byte;
1)	  if (k>=fnt←def1)and(k<fnt←def1+4) then
1)	    begin p:=first←par(k); define←font(p); k:=nop;
1)	    end;
1)	  until k<>nop;
1)	  if k=post then
1)	    begin in←postamble:=true; goto done;
1)	    end;
1)	  if k<>bop then bad←dvi('byte ',cur←loc-1:0,' is not bop');
1)	@.byte n is not bop@>
1)	  @<Pass a |bop|...@>;
1)	  end;
1)	done:end
**** File 2) DVITYP.WEB[PAS,DEK]/15P/79L
2)	begin while max_pages>0 do
2)		begin decr(max_pages);
2)		print_ln(' '); print(cur_loc-45:0,': beginning of page ');
2)		for k←0 to start_vals do
2)			begin print(count[k]:0);
2)			if k<start_vals then print('.')
2)			else print_ln(' ');
2)			end;
2)		if not do_page then abort('page ended unexpectedly!');
2)	@.page ended unexpectedly@>
2)		repeat k←get_byte;
2)		if (k≥fnt_def1)∧(k<fnt_def1+4) then
2)			begin p←first_par(k); define_font(p); k←nop;
2)			end;
2)		until k≠nop;
2)		if k=post then
2)			begin in_postamble←true; goto done;
2)			end;
2)		if k≠bop then bad_dvi('byte ',cur_loc-1:0,' is not bop');
2)	@.byte n is not bop@>
2)		@<Pass a |bop|...@>;
2)		end;
2)	done:end
***************